xref: /netbsd-src/external/bsd/ntp/dist/sntp/libopts/numeric.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: numeric.c,v 1.1.1.1 2009/12/13 16:57:18 kardel Exp $	*/
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 =*/
41 void
42 optionShowRange(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 =*/
114 void
115 optionNumericVal(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