123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- /**
- * \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;
- fprintf(option_usage_fp, zRangeErr, pOpts->pzProgName,
- pOD->pz_Name, pOD->optArg.argInt);
- pz_indent = "";
- }
- if (pOD->fOptState & OPTST_SCALED_NUM)
- fprintf(option_usage_fp, zRangeScaled, pz_indent);
- fprintf(option_usage_fp, (rng_ct > 1) ? zRangeLie : zRangeOnly, pz_indent);
- pz_indent = (pOpts != OPTPROC_EMIT_USAGE)
- ? ONE_TAB_STR
- : (zTabSpace + tab_skip_ct);
- for (;;) {
- if (rng->rmax == LONG_MIN)
- fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin);
- else if (rng->rmin == LONG_MIN)
- fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax);
- else if (rng->rmax == LONG_MAX)
- fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin);
- else
- fprintf(option_usage_fp, zRange, pz_indent, rng->rmin,
- rng->rmax);
- if (--rng_ct <= 0) {
- fputc(NL, option_usage_fp);
- break;
- }
- fputs(zRangeOr, option_usage_fp);
- rng++;
- }
- 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;
- }
- od->optArg.argInt = val;
- return;
- bad_number:
- fprintf( stderr, zNotNumber, opts->pzProgName, od->optArg.argString );
- if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
- (*(opts->pUsageProc))(opts, EXIT_FAILURE);
- errno = EINVAL;
- od->optArg.argInt = ~0;
- }
- /** @}
- *
- * Local Variables:
- * mode: C
- * c-file-style: "stroustrup"
- * indent-tabs-mode: nil
- * End:
- * end of autoopts/numeric.c */
|