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