1181834Sroberto 2290001Sglebius/** 3290001Sglebius * \file numeric.c 4290001Sglebius * 5290001Sglebius * Handle options with numeric (integer) arguments. 6290001Sglebius * 7290001Sglebius * @addtogroup autoopts 8290001Sglebius * @{ 9181834Sroberto */ 10181834Sroberto/* 11290001Sglebius * This file is part of AutoOpts, a companion to AutoGen. 12290001Sglebius * AutoOpts is free software. 13290001Sglebius * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved 14181834Sroberto * 15290001Sglebius * AutoOpts is available under any one of two licenses. The license 16290001Sglebius * in use must be one of these two and the choice is under the control 17290001Sglebius * of the user of the license. 18181834Sroberto * 19290001Sglebius * The GNU Lesser General Public License, version 3 or later 20290001Sglebius * See the files "COPYING.lgplv3" and "COPYING.gplv3" 21181834Sroberto * 22290001Sglebius * The Modified Berkeley Software Distribution License 23290001Sglebius * See the file "COPYING.mbsd" 24181834Sroberto * 25290001Sglebius * These files have the following sha256 sums: 26181834Sroberto * 27290001Sglebius * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 28290001Sglebius * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 29290001Sglebius * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd 30290001Sglebius */ 31290001Sglebius 32290001Sglebius/*=export_func optionShowRange 33290001Sglebius * private: 34181834Sroberto * 35290001Sglebius * what: Show info about range constraints 36290001Sglebius * arg: + tOptions * + pOpts + program options descriptor + 37290001Sglebius * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + 38290001Sglebius * arg: + void * + rng_table + the value range tables + 39290001Sglebius * arg: + int + rng_count + the number of entries + 40181834Sroberto * 41290001Sglebius * doc: 42290001Sglebius * Show information about a numeric option with range constraints. 43290001Sglebius=*/ 44290001Sglebiusvoid 45290001SglebiusoptionShowRange(tOptions * pOpts, tOptDesc * pOD, void * rng_table, int rng_ct) 46290001Sglebius{ 47290001Sglebius const struct {long const rmin, rmax;} * rng = rng_table; 48181834Sroberto 49290001Sglebius char const * pz_indent = zTabHyp + tab_skip_ct; 50290001Sglebius 51290001Sglebius /* 52290001Sglebius * The range is shown only for full usage requests and an error 53290001Sglebius * in this particular option. 54290001Sglebius */ 55290001Sglebius if (pOpts != OPTPROC_EMIT_USAGE) { 56290001Sglebius if (pOpts <= OPTPROC_EMIT_LIMIT) 57290001Sglebius return; 58290001Sglebius pz_indent = ONE_TAB_STR; 59290001Sglebius 60290001Sglebius fprintf(option_usage_fp, zRangeErr, pOpts->pzProgName, 61290001Sglebius pOD->pz_Name, pOD->optArg.argInt); 62290001Sglebius pz_indent = ""; 63290001Sglebius } 64290001Sglebius 65290001Sglebius if (pOD->fOptState & OPTST_SCALED_NUM) 66290001Sglebius fprintf(option_usage_fp, zRangeScaled, pz_indent); 67290001Sglebius 68290001Sglebius fprintf(option_usage_fp, (rng_ct > 1) ? zRangeLie : zRangeOnly, pz_indent); 69290001Sglebius pz_indent = (pOpts != OPTPROC_EMIT_USAGE) 70290001Sglebius ? ONE_TAB_STR 71290001Sglebius : (zTabSpace + tab_skip_ct); 72290001Sglebius 73290001Sglebius for (;;) { 74290001Sglebius if (rng->rmax == LONG_MIN) 75290001Sglebius fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin); 76290001Sglebius else if (rng->rmin == LONG_MIN) 77290001Sglebius fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax); 78290001Sglebius else if (rng->rmax == LONG_MAX) 79290001Sglebius fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin); 80290001Sglebius else 81290001Sglebius fprintf(option_usage_fp, zRange, pz_indent, rng->rmin, 82290001Sglebius rng->rmax); 83290001Sglebius 84290001Sglebius if (--rng_ct <= 0) { 85290001Sglebius fputc(NL, option_usage_fp); 86290001Sglebius break; 87290001Sglebius } 88290001Sglebius fputs(zRangeOr, option_usage_fp); 89290001Sglebius rng++; 90290001Sglebius } 91290001Sglebius 92290001Sglebius if (pOpts > OPTPROC_EMIT_LIMIT) 93290001Sglebius pOpts->pUsageProc(pOpts, EXIT_FAILURE); 94290001Sglebius} 95290001Sglebius 96181834Sroberto/*=export_func optionNumericVal 97181834Sroberto * private: 98181834Sroberto * 99290001Sglebius * what: process an option with a numeric value. 100290001Sglebius * arg: + tOptions * + opts + program options descriptor + 101290001Sglebius * arg: + tOptDesc * + od + the descriptor for this arg + 102181834Sroberto * 103181834Sroberto * doc: 104181834Sroberto * Decipher a numeric value. 105181834Sroberto=*/ 106181834Srobertovoid 107290001SglebiusoptionNumericVal(tOptions * opts, tOptDesc * od) 108181834Sroberto{ 109290001Sglebius char * pz; 110290001Sglebius long val; 111181834Sroberto 112181834Sroberto /* 113290001Sglebius * Guard against all the different ways this procedure might get invoked 114290001Sglebius * when there is no string argument provided. 115290001Sglebius */ 116290001Sglebius if (INQUERY_CALL(opts, od) || (od->optArg.argString == NULL)) 117290001Sglebius return; 118290001Sglebius 119290001Sglebius /* 120181834Sroberto * Numeric options may have a range associated with it. 121181834Sroberto * If it does, the usage procedure requests that it be 122290001Sglebius * emitted by passing a NULL od pointer. Also bail out 123290001Sglebius * if there is no option argument or if we are being reset. 124181834Sroberto */ 125290001Sglebius if ( (od == NULL) 126290001Sglebius || (od->optArg.argString == NULL) 127290001Sglebius || ((od->fOptState & OPTST_RESET) != 0)) 128181834Sroberto return; 129181834Sroberto 130290001Sglebius errno = 0; 131290001Sglebius val = strtol(od->optArg.argString, &pz, 0); 132290001Sglebius if ((pz == od->optArg.argString) || (errno != 0)) 133290001Sglebius goto bad_number; 134181834Sroberto 135290001Sglebius if ((od->fOptState & OPTST_SCALED_NUM) != 0) 136290001Sglebius switch (*(pz++)) { 137290001Sglebius case NUL: pz--; break; 138290001Sglebius case 't': val *= 1000; 139290001Sglebius case 'g': val *= 1000; 140290001Sglebius case 'm': val *= 1000; 141290001Sglebius case 'k': val *= 1000; break; 142290001Sglebius 143290001Sglebius case 'T': val *= 1024; 144290001Sglebius case 'G': val *= 1024; 145290001Sglebius case 'M': val *= 1024; 146290001Sglebius case 'K': val *= 1024; break; 147290001Sglebius 148290001Sglebius default: goto bad_number; 149290001Sglebius } 150290001Sglebius 151290001Sglebius if (*pz != NUL) 152290001Sglebius goto bad_number; 153290001Sglebius 154290001Sglebius if (od->fOptState & OPTST_ALLOC_ARG) { 155290001Sglebius AGFREE(od->optArg.argString); 156290001Sglebius od->fOptState &= ~OPTST_ALLOC_ARG; 157181834Sroberto } 158181834Sroberto 159290001Sglebius od->optArg.argInt = val; 160290001Sglebius return; 161290001Sglebius 162290001Sglebius bad_number: 163290001Sglebius 164290001Sglebius fprintf( stderr, zNotNumber, opts->pzProgName, od->optArg.argString ); 165290001Sglebius if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) 166290001Sglebius (*(opts->pUsageProc))(opts, EXIT_FAILURE); 167290001Sglebius 168290001Sglebius errno = EINVAL; 169290001Sglebius od->optArg.argInt = ~0; 170181834Sroberto} 171290001Sglebius 172290001Sglebius/** @} 173290001Sglebius * 174181834Sroberto * Local Variables: 175181834Sroberto * mode: C 176181834Sroberto * c-file-style: "stroustrup" 177181834Sroberto * indent-tabs-mode: nil 178181834Sroberto * End: 179181834Sroberto * end of autoopts/numeric.c */ 180