1181834Sroberto 2285612Sdelphij/** 3285612Sdelphij * \file numeric.c 4285612Sdelphij * 5285612Sdelphij * Handle options with numeric (integer) arguments. 6285612Sdelphij * 7285612Sdelphij * @addtogroup autoopts 8285612Sdelphij * @{ 9181834Sroberto */ 10181834Sroberto/* 11285612Sdelphij * This file is part of AutoOpts, a companion to AutoGen. 12285612Sdelphij * AutoOpts is free software. 13285612Sdelphij * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved 14181834Sroberto * 15285612Sdelphij * AutoOpts is available under any one of two licenses. The license 16285612Sdelphij * in use must be one of these two and the choice is under the control 17285612Sdelphij * of the user of the license. 18181834Sroberto * 19285612Sdelphij * The GNU Lesser General Public License, version 3 or later 20285612Sdelphij * See the files "COPYING.lgplv3" and "COPYING.gplv3" 21181834Sroberto * 22285612Sdelphij * The Modified Berkeley Software Distribution License 23285612Sdelphij * See the file "COPYING.mbsd" 24181834Sroberto * 25285612Sdelphij * These files have the following sha256 sums: 26181834Sroberto * 27285612Sdelphij * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 28285612Sdelphij * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 29285612Sdelphij * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd 30285612Sdelphij */ 31285612Sdelphij 32285612Sdelphij/*=export_func optionShowRange 33285612Sdelphij * private: 34181834Sroberto * 35285612Sdelphij * what: Show info about range constraints 36285612Sdelphij * arg: + tOptions * + pOpts + program options descriptor + 37285612Sdelphij * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + 38285612Sdelphij * arg: + void * + rng_table + the value range tables + 39285612Sdelphij * arg: + int + rng_count + the number of entries + 40181834Sroberto * 41285612Sdelphij * doc: 42285612Sdelphij * Show information about a numeric option with range constraints. 43285612Sdelphij=*/ 44285612Sdelphijvoid 45285612SdelphijoptionShowRange(tOptions * pOpts, tOptDesc * pOD, void * rng_table, int rng_ct) 46285612Sdelphij{ 47285612Sdelphij const struct {long const rmin, rmax;} * rng = rng_table; 48181834Sroberto 49285612Sdelphij char const * pz_indent = zTabHyp + tab_skip_ct; 50285612Sdelphij 51285612Sdelphij /* 52285612Sdelphij * The range is shown only for full usage requests and an error 53285612Sdelphij * in this particular option. 54285612Sdelphij */ 55285612Sdelphij if (pOpts != OPTPROC_EMIT_USAGE) { 56285612Sdelphij if (pOpts <= OPTPROC_EMIT_LIMIT) 57285612Sdelphij return; 58285612Sdelphij pz_indent = ONE_TAB_STR; 59285612Sdelphij 60285612Sdelphij fprintf(option_usage_fp, zRangeErr, pOpts->pzProgName, 61285612Sdelphij pOD->pz_Name, pOD->optArg.argInt); 62285612Sdelphij pz_indent = ""; 63285612Sdelphij } 64285612Sdelphij 65285612Sdelphij if (pOD->fOptState & OPTST_SCALED_NUM) 66285612Sdelphij fprintf(option_usage_fp, zRangeScaled, pz_indent); 67285612Sdelphij 68285612Sdelphij fprintf(option_usage_fp, (rng_ct > 1) ? zRangeLie : zRangeOnly, pz_indent); 69285612Sdelphij pz_indent = (pOpts != OPTPROC_EMIT_USAGE) 70285612Sdelphij ? ONE_TAB_STR 71285612Sdelphij : (zTabSpace + tab_skip_ct); 72285612Sdelphij 73285612Sdelphij for (;;) { 74285612Sdelphij if (rng->rmax == LONG_MIN) 75285612Sdelphij fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin); 76285612Sdelphij else if (rng->rmin == LONG_MIN) 77285612Sdelphij fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax); 78285612Sdelphij else if (rng->rmax == LONG_MAX) 79285612Sdelphij fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin); 80285612Sdelphij else 81285612Sdelphij fprintf(option_usage_fp, zRange, pz_indent, rng->rmin, 82285612Sdelphij rng->rmax); 83285612Sdelphij 84285612Sdelphij if (--rng_ct <= 0) { 85285612Sdelphij fputc(NL, option_usage_fp); 86285612Sdelphij break; 87285612Sdelphij } 88285612Sdelphij fputs(zRangeOr, option_usage_fp); 89285612Sdelphij rng++; 90285612Sdelphij } 91285612Sdelphij 92285612Sdelphij if (pOpts > OPTPROC_EMIT_LIMIT) 93285612Sdelphij pOpts->pUsageProc(pOpts, EXIT_FAILURE); 94285612Sdelphij} 95285612Sdelphij 96181834Sroberto/*=export_func optionNumericVal 97181834Sroberto * private: 98181834Sroberto * 99285612Sdelphij * what: process an option with a numeric value. 100285612Sdelphij * arg: + tOptions * + opts + program options descriptor + 101285612Sdelphij * arg: + tOptDesc * + od + the descriptor for this arg + 102181834Sroberto * 103181834Sroberto * doc: 104181834Sroberto * Decipher a numeric value. 105181834Sroberto=*/ 106181834Srobertovoid 107285612SdelphijoptionNumericVal(tOptions * opts, tOptDesc * od) 108181834Sroberto{ 109285612Sdelphij char * pz; 110285612Sdelphij long val; 111181834Sroberto 112181834Sroberto /* 113285612Sdelphij * Guard against all the different ways this procedure might get invoked 114285612Sdelphij * when there is no string argument provided. 115285612Sdelphij */ 116285612Sdelphij if (INQUERY_CALL(opts, od) || (od->optArg.argString == NULL)) 117285612Sdelphij return; 118285612Sdelphij 119285612Sdelphij /* 120181834Sroberto * Numeric options may have a range associated with it. 121181834Sroberto * If it does, the usage procedure requests that it be 122285612Sdelphij * emitted by passing a NULL od pointer. Also bail out 123285612Sdelphij * if there is no option argument or if we are being reset. 124181834Sroberto */ 125285612Sdelphij if ( (od == NULL) 126285612Sdelphij || (od->optArg.argString == NULL) 127285612Sdelphij || ((od->fOptState & OPTST_RESET) != 0)) 128181834Sroberto return; 129181834Sroberto 130285612Sdelphij errno = 0; 131285612Sdelphij val = strtol(od->optArg.argString, &pz, 0); 132285612Sdelphij if ((pz == od->optArg.argString) || (errno != 0)) 133285612Sdelphij goto bad_number; 134181834Sroberto 135285612Sdelphij if ((od->fOptState & OPTST_SCALED_NUM) != 0) 136285612Sdelphij switch (*(pz++)) { 137285612Sdelphij case NUL: pz--; break; 138285612Sdelphij case 't': val *= 1000; 139285612Sdelphij case 'g': val *= 1000; 140285612Sdelphij case 'm': val *= 1000; 141285612Sdelphij case 'k': val *= 1000; break; 142285612Sdelphij 143285612Sdelphij case 'T': val *= 1024; 144285612Sdelphij case 'G': val *= 1024; 145285612Sdelphij case 'M': val *= 1024; 146285612Sdelphij case 'K': val *= 1024; break; 147285612Sdelphij 148285612Sdelphij default: goto bad_number; 149285612Sdelphij } 150285612Sdelphij 151285612Sdelphij if (*pz != NUL) 152285612Sdelphij goto bad_number; 153285612Sdelphij 154285612Sdelphij if (od->fOptState & OPTST_ALLOC_ARG) { 155285612Sdelphij AGFREE(od->optArg.argString); 156285612Sdelphij od->fOptState &= ~OPTST_ALLOC_ARG; 157181834Sroberto } 158181834Sroberto 159285612Sdelphij od->optArg.argInt = val; 160285612Sdelphij return; 161285612Sdelphij 162285612Sdelphij bad_number: 163285612Sdelphij 164285612Sdelphij fprintf( stderr, zNotNumber, opts->pzProgName, od->optArg.argString ); 165285612Sdelphij if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) 166285612Sdelphij (*(opts->pUsageProc))(opts, EXIT_FAILURE); 167285612Sdelphij 168285612Sdelphij errno = EINVAL; 169285612Sdelphij od->optArg.argInt = ~0; 170181834Sroberto} 171285612Sdelphij 172285612Sdelphij/** @} 173285612Sdelphij * 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