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