1
2/*
3 *  $Id: 52d772d69bed7f2911d88ff17b9a44308d6ca0b1 $
4 *  Time-stamp:      "2009-07-23 17:25:39 bkorb"
5 *
6 *  This file is part of AutoOpts, a companion to AutoGen.
7 *  AutoOpts is free software.
8 *  AutoOpts is copyright (c) 1992-2009 by Bruce Korb - all rights reserved
9 *
10 *  AutoOpts is available under any one of two licenses.  The license
11 *  in use must be one of these two and the choice is under the control
12 *  of the user of the license.
13 *
14 *   The GNU Lesser General Public License, version 3 or later
15 *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
16 *
17 *   The Modified Berkeley Software Distribution License
18 *      See the file "COPYING.mbsd"
19 *
20 *  These files have the following md5sums:
21 *
22 *  43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
23 *  06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
24 *  66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
25 */
26
27/*=export_func  optionShowRange
28 * private:
29 *
30 * what:
31 * arg:   + tOptions* + pOpts     + program options descriptor  +
32 * arg:   + tOptDesc* + pOptDesc  + the descriptor for this arg +
33 * arg:   + void *    + rng_table + the value range tables      +
34 * arg:   + int       + rng_count + the number of entries       +
35 *
36 * doc:
37 *   Show information about a numeric option with range constraints.
38=*/
39void
40optionShowRange(tOptions* pOpts, tOptDesc* pOD, void * rng_table, int rng_ct)
41{
42    static char const bullet[] = "\t\t\t\t- ";
43    static char const deepin[] = "\t\t\t\t  ";
44    static char const onetab[] = "\t";
45
46    const struct {long const rmin, rmax;} * rng = rng_table;
47
48    char const * pz_indent =
49        (pOpts != OPTPROC_EMIT_USAGE) ? onetab : bullet;
50
51    if ((pOpts == OPTPROC_EMIT_USAGE) || (pOpts > OPTPROC_EMIT_LIMIT)) {
52        char const * lie_in_range = zRangeLie;
53
54        if (pOpts > OPTPROC_EMIT_LIMIT) {
55            fprintf(option_usage_fp, zRangeErr,
56                    pOpts->pzProgName, pOD->pz_Name, pOD->optArg.argString);
57            fprintf(option_usage_fp, "The %s option:\n", pOD->pz_Name);
58            lie_in_range = zRangeBadLie;
59            pz_indent = "";
60        }
61
62        if (pOD->fOptState & OPTST_SCALED_NUM)
63            fprintf(option_usage_fp, zRangeScaled, pz_indent);
64
65        if (rng_ct > 1) {
66            fprintf(option_usage_fp, lie_in_range, pz_indent);
67            pz_indent =
68                (pOpts != OPTPROC_EMIT_USAGE) ? onetab : deepin;
69
70        } else {
71            fprintf(option_usage_fp, zRangeOnly, pz_indent);
72            pz_indent = onetab + 1; /* empty string */
73        }
74
75        for (;;) {
76            if (rng->rmax == LONG_MIN)
77                fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin);
78            else if (rng->rmin == LONG_MIN)
79                fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax);
80            else if (rng->rmax == LONG_MAX)
81                fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin);
82            else
83                fprintf(option_usage_fp, zRange, pz_indent, rng->rmin,
84                        rng->rmax);
85
86            if  (--rng_ct <= 0) {
87                fputc('\n', option_usage_fp);
88                break;
89            }
90            fputs(zRangeOr, option_usage_fp);
91            rng++;
92            pz_indent =
93                (pOpts != OPTPROC_EMIT_USAGE) ? onetab : deepin;
94        }
95
96        if (pOpts > OPTPROC_EMIT_LIMIT)
97            pOpts->pUsageProc(pOpts, EXIT_FAILURE);
98    }
99}
100
101
102/*=export_func  optionNumericVal
103 * private:
104 *
105 * what:  process an option with a numeric value.
106 * arg:   + tOptions* + pOpts    + program options descriptor +
107 * arg:   + tOptDesc* + pOptDesc + the descriptor for this arg +
108 *
109 * doc:
110 *  Decipher a numeric value.
111=*/
112void
113optionNumericVal(tOptions* pOpts, tOptDesc* pOD )
114{
115    char* pz;
116    long  val;
117
118    /*
119     *  Numeric options may have a range associated with it.
120     *  If it does, the usage procedure requests that it be
121     *  emitted by passing a NULL pOD pointer.  Also bail out
122     *  if there is no option argument or if we are being reset.
123     */
124    if (  (pOD == NULL)
125       || (pOD->optArg.argString == NULL)
126       || ((pOD->fOptState & OPTST_RESET) != 0))
127        return;
128
129    errno = 0;
130    val = strtol(pOD->optArg.argString, &pz, 0);
131    if ((pz == pOD->optArg.argString) || (errno != 0))
132        goto bad_number;
133
134    if ((pOD->fOptState & OPTST_SCALED_NUM) != 0)
135        switch (*(pz++)) {
136        case '\0': pz--; break;
137        case 't':  val *= 1000;
138        case 'g':  val *= 1000;
139        case 'm':  val *= 1000;
140        case 'k':  val *= 1000; break;
141
142        case 'T':  val *= 1024;
143        case 'G':  val *= 1024;
144        case 'M':  val *= 1024;
145        case 'K':  val *= 1024; break;
146
147        default:   goto bad_number;
148        }
149
150    if (*pz != NUL)
151        goto bad_number;
152
153    if (pOD->fOptState & OPTST_ALLOC_ARG) {
154        AGFREE(pOD->optArg.argString);
155        pOD->fOptState &= ~OPTST_ALLOC_ARG;
156    }
157
158    pOD->optArg.argInt = val;
159    return;
160
161    bad_number:
162
163    fprintf( stderr, zNotNumber, pOpts->pzProgName, pOD->optArg.argString );
164    if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
165        (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
166
167    pOD->optArg.argInt = ~0;
168}
169
170/*
171 * Local Variables:
172 * mode: C
173 * c-file-style: "stroustrup"
174 * indent-tabs-mode: nil
175 * End:
176 * end of autoopts/numeric.c */
177