/**
* \file numeric.c
*
* Handle options with numeric (integer) arguments.
*
* @addtogroup autoopts
* @{
*/
/*
* This file is part of AutoOpts, a companion to AutoGen.
* AutoOpts is free software.
* AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved
*
* AutoOpts is available under any one of two licenses. The license
* in use must be one of these two and the choice is under the control
* of the user of the license.
*
* The GNU Lesser General Public License, version 3 or later
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
*
* The Modified Berkeley Software Distribution License
* See the file "COPYING.mbsd"
*
* These files have the following sha256 sums:
*
* 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
* 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
* 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
*/
/*=export_func optionShowRange
* private:
*
* what: Show info about range constraints
* arg: + tOptions * + pOpts + program options descriptor +
* arg: + tOptDesc * + pOptDesc + the descriptor for this arg +
* arg: + void * + rng_table + the value range tables +
* arg: + int + rng_count + the number of entries +
*
* doc:
* Show information about a numeric option with range constraints.
=*/
void
optionShowRange(tOptions * pOpts, tOptDesc * pOD, void * rng_table, int rng_ct)
{
const struct {long const rmin, rmax;} * rng = rng_table;
char const * pz_indent = zTabHyp + tab_skip_ct;
/*
* The range is shown only for full usage requests and an error
* in this particular option.
*/
if (pOpts != OPTPROC_EMIT_USAGE) {
if (pOpts <= OPTPROC_EMIT_LIMIT)
return;
pz_indent = ONE_TAB_STR;
if (pOpts > OPTPROC_EMIT_LIMIT)
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
}
/*=export_func optionNumericVal
* private:
*
* what: process an option with a numeric value.
* arg: + tOptions * + opts + program options descriptor +
* arg: + tOptDesc * + od + the descriptor for this arg +
*
* doc:
* Decipher a numeric value.
=*/
void
optionNumericVal(tOptions * opts, tOptDesc * od)
{
char * pz;
long val;
/*
* Guard against all the different ways this procedure might get invoked
* when there is no string argument provided.
*/
if (INQUERY_CALL(opts, od) || (od->optArg.argString == NULL))
return;
/*
* Numeric options may have a range associated with it.
* If it does, the usage procedure requests that it be
* emitted by passing a NULL od pointer. Also bail out
* if there is no option argument or if we are being reset.
*/
if ( (od == NULL)
|| (od->optArg.argString == NULL)
|| ((od->fOptState & OPTST_RESET) != 0)
|| (opts <= OPTPROC_EMIT_LIMIT))
return;
errno = 0;
val = strtol(od->optArg.argString, &pz, 0);
if ((pz == od->optArg.argString) || (errno != 0))
goto bad_number;
if ((od->fOptState & OPTST_SCALED_NUM) != 0)
switch (*(pz++)) {
case NUL: pz--; break;
case 't': val *= 1000; /* FALLTHROUGH */
case 'g': val *= 1000; /* FALLTHROUGH */
case 'm': val *= 1000; /* FALLTHROUGH */
case 'k': val *= 1000; break;
case 'T': val *= 1024; /* FALLTHROUGH */
case 'G': val *= 1024; /* FALLTHROUGH */
case 'M': val *= 1024; /* FALLTHROUGH */
case 'K': val *= 1024; break;
default: goto bad_number;
}
if (*pz != NUL)
goto bad_number;
if (od->fOptState & OPTST_ALLOC_ARG) {
AGFREE(od->optArg.argString);
od->fOptState &= ~OPTST_ALLOC_ARG;
}