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