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