numeric.c revision 280849
1181834Sroberto 2280849Scy/** 3280849Scy * \file numeric.c 4280849Scy * 5280849Scy * Handle options with numeric (integer) arguments. 6280849Scy * 7280849Scy * @addtogroup autoopts 8280849Scy * @{ 9181834Sroberto */ 10181834Sroberto/* 11280849Scy * This file is part of AutoOpts, a companion to AutoGen. 12280849Scy * AutoOpts is free software. 13280849Scy * AutoOpts is Copyright (C) 1992-2014 by Bruce Korb - all rights reserved 14181834Sroberto * 15280849Scy * AutoOpts is available under any one of two licenses. The license 16280849Scy * in use must be one of these two and the choice is under the control 17280849Scy * of the user of the license. 18181834Sroberto * 19280849Scy * The GNU Lesser General Public License, version 3 or later 20280849Scy * See the files "COPYING.lgplv3" and "COPYING.gplv3" 21181834Sroberto * 22280849Scy * The Modified Berkeley Software Distribution License 23280849Scy * See the file "COPYING.mbsd" 24181834Sroberto * 25280849Scy * These files have the following sha256 sums: 26181834Sroberto * 27280849Scy * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 28280849Scy * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 29280849Scy * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd 30280849Scy */ 31280849Scy 32280849Scy/*=export_func optionShowRange 33280849Scy * private: 34181834Sroberto * 35280849Scy * what: Show info about range constraints 36280849Scy * arg: + tOptions* + pOpts + program options descriptor + 37280849Scy * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + 38280849Scy * arg: + void * + rng_table + the value range tables + 39280849Scy * arg: + int + rng_count + the number of entries + 40181834Sroberto * 41280849Scy * doc: 42280849Scy * Show information about a numeric option with range constraints. 43280849Scy=*/ 44280849Scyvoid 45280849ScyoptionShowRange(tOptions * pOpts, tOptDesc * pOD, const void * rng_table, int rng_ct) 46280849Scy{ 47280849Scy const struct {long const rmin, rmax;} * rng = rng_table; 48181834Sroberto 49280849Scy char const * pz_indent = zTabHyp + tab_skip_ct; 50280849Scy 51280849Scy /* 52280849Scy * The range is shown only for full usage requests and an error 53280849Scy * in this particular option. 54280849Scy */ 55280849Scy if (pOpts != OPTPROC_EMIT_USAGE) { 56280849Scy if (pOpts <= OPTPROC_EMIT_LIMIT) 57280849Scy return; 58280849Scy pz_indent = ONE_TAB_STR; 59280849Scy 60280849Scy fprintf(option_usage_fp, zRangeErr, pOpts->pzProgName, 61280849Scy pOD->pz_Name, pOD->optArg.argInt); 62280849Scy pz_indent = ""; 63280849Scy } 64280849Scy 65280849Scy if (pOD->fOptState & OPTST_SCALED_NUM) 66280849Scy fprintf(option_usage_fp, zRangeScaled, pz_indent); 67280849Scy 68280849Scy fprintf(option_usage_fp, (rng_ct > 1) ? zRangeLie : zRangeOnly, pz_indent); 69280849Scy pz_indent = (pOpts != OPTPROC_EMIT_USAGE) 70280849Scy ? ONE_TAB_STR 71280849Scy : (zTabSpace + tab_skip_ct); 72280849Scy 73280849Scy for (;;) { 74280849Scy if (rng->rmax == LONG_MIN) 75280849Scy fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin); 76280849Scy else if (rng->rmin == LONG_MIN) 77280849Scy fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax); 78280849Scy else if (rng->rmax == LONG_MAX) 79280849Scy fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin); 80280849Scy else 81280849Scy fprintf(option_usage_fp, zRange, pz_indent, rng->rmin, 82280849Scy rng->rmax); 83280849Scy 84280849Scy if (--rng_ct <= 0) { 85280849Scy fputc(NL, option_usage_fp); 86280849Scy break; 87280849Scy } 88280849Scy fputs(zRangeOr, option_usage_fp); 89280849Scy rng++; 90280849Scy } 91280849Scy 92280849Scy if (pOpts > OPTPROC_EMIT_LIMIT) 93280849Scy pOpts->pUsageProc(pOpts, EXIT_FAILURE); 94280849Scy} 95280849Scy 96181834Sroberto/*=export_func optionNumericVal 97181834Sroberto * private: 98181834Sroberto * 99280849Scy * what: process an option with a numeric value. 100280849Scy * arg: + tOptions* + opts + program options descriptor + 101280849Scy * arg: + tOptDesc* + od + the descriptor for this arg + 102181834Sroberto * 103181834Sroberto * doc: 104181834Sroberto * Decipher a numeric value. 105181834Sroberto=*/ 106181834Srobertovoid 107280849ScyoptionNumericVal(tOptions * opts, tOptDesc * od) 108181834Sroberto{ 109181834Sroberto char* pz; 110181834Sroberto long val; 111181834Sroberto 112181834Sroberto /* 113280849Scy * Guard against all the different ways this procedure might get invoked 114280849Scy * when there is no string argument provided. 115280849Scy */ 116280849Scy if (INQUERY_CALL(opts, od) || (od->optArg.argString == NULL)) 117280849Scy return; 118280849Scy 119280849Scy /* 120181834Sroberto * Numeric options may have a range associated with it. 121181834Sroberto * If it does, the usage procedure requests that it be 122280849Scy * emitted by passing a NULL od pointer. Also bail out 123280849Scy * if there is no option argument or if we are being reset. 124181834Sroberto */ 125280849Scy if ( (od == NULL) 126280849Scy || (od->optArg.argString == NULL) 127280849Scy || ((od->fOptState & OPTST_RESET) != 0)) 128181834Sroberto return; 129181834Sroberto 130280849Scy errno = 0; 131280849Scy val = strtol(od->optArg.argString, &pz, 0); 132280849Scy if ((pz == od->optArg.argString) || (errno != 0)) 133280849Scy goto bad_number; 134181834Sroberto 135280849Scy if ((od->fOptState & OPTST_SCALED_NUM) != 0) 136280849Scy switch (*(pz++)) { 137280849Scy case NUL: pz--; break; 138280849Scy case 't': val *= 1000; 139280849Scy case 'g': val *= 1000; 140280849Scy case 'm': val *= 1000; 141280849Scy case 'k': val *= 1000; break; 142280849Scy 143280849Scy case 'T': val *= 1024; 144280849Scy case 'G': val *= 1024; 145280849Scy case 'M': val *= 1024; 146280849Scy case 'K': val *= 1024; break; 147280849Scy 148280849Scy default: goto bad_number; 149280849Scy } 150280849Scy 151280849Scy if (*pz != NUL) 152280849Scy goto bad_number; 153280849Scy 154280849Scy if (od->fOptState & OPTST_ALLOC_ARG) { 155280849Scy AGFREE(od->optArg.argString); 156280849Scy od->fOptState &= ~OPTST_ALLOC_ARG; 157181834Sroberto } 158181834Sroberto 159280849Scy od->optArg.argInt = val; 160280849Scy return; 161280849Scy 162280849Scy bad_number: 163280849Scy 164280849Scy fprintf( stderr, zNotNumber, opts->pzProgName, od->optArg.argString ); 165280849Scy if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) 166280849Scy (*(opts->pUsageProc))(opts, EXIT_FAILURE); 167280849Scy 168280849Scy errno = EINVAL; 169280849Scy od->optArg.argInt = ~0; 170181834Sroberto} 171280849Scy 172280849Scy/** @} 173280849Scy * 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