numeric.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /**
  2. * \file numeric.c
  3. *
  4. * Handle options with numeric (integer) arguments.
  5. *
  6. * @addtogroup autoopts
  7. * @{
  8. */
  9. /*
  10. * This file is part of AutoOpts, a companion to AutoGen.
  11. * AutoOpts is free software.
  12. * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved
  13. *
  14. * AutoOpts is available under any one of two licenses. The license
  15. * in use must be one of these two and the choice is under the control
  16. * of the user of the license.
  17. *
  18. * The GNU Lesser General Public License, version 3 or later
  19. * See the files "COPYING.lgplv3" and "COPYING.gplv3"
  20. *
  21. * The Modified Berkeley Software Distribution License
  22. * See the file "COPYING.mbsd"
  23. *
  24. * These files have the following sha256 sums:
  25. *
  26. * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
  27. * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
  28. * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
  29. */
  30. /*=export_func optionShowRange
  31. * private:
  32. *
  33. * what: Show info about range constraints
  34. * arg: + tOptions * + pOpts + program options descriptor +
  35. * arg: + tOptDesc * + pOptDesc + the descriptor for this arg +
  36. * arg: + void * + rng_table + the value range tables +
  37. * arg: + int + rng_count + the number of entries +
  38. *
  39. * doc:
  40. * Show information about a numeric option with range constraints.
  41. =*/
  42. void
  43. optionShowRange(tOptions * pOpts, tOptDesc * pOD, void * rng_table, int rng_ct)
  44. {
  45. const struct {long const rmin, rmax;} * rng = rng_table;
  46. char const * pz_indent = zTabHyp + tab_skip_ct;
  47. /*
  48. * The range is shown only for full usage requests and an error
  49. * in this particular option.
  50. */
  51. if (pOpts != OPTPROC_EMIT_USAGE) {
  52. if (pOpts <= OPTPROC_EMIT_LIMIT)
  53. return;
  54. pz_indent = ONE_TAB_STR;
  55. fprintf(option_usage_fp, zRangeErr, pOpts->pzProgName,
  56. pOD->pz_Name, pOD->optArg.argInt);
  57. pz_indent = "";
  58. }
  59. if (pOD->fOptState & OPTST_SCALED_NUM)
  60. fprintf(option_usage_fp, zRangeScaled, pz_indent);
  61. fprintf(option_usage_fp, (rng_ct > 1) ? zRangeLie : zRangeOnly, pz_indent);
  62. pz_indent = (pOpts != OPTPROC_EMIT_USAGE)
  63. ? ONE_TAB_STR
  64. : (zTabSpace + tab_skip_ct);
  65. for (;;) {
  66. if (rng->rmax == LONG_MIN)
  67. fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin);
  68. else if (rng->rmin == LONG_MIN)
  69. fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax);
  70. else if (rng->rmax == LONG_MAX)
  71. fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin);
  72. else
  73. fprintf(option_usage_fp, zRange, pz_indent, rng->rmin,
  74. rng->rmax);
  75. if (--rng_ct <= 0) {
  76. fputc(NL, option_usage_fp);
  77. break;
  78. }
  79. fputs(zRangeOr, option_usage_fp);
  80. rng++;
  81. }
  82. if (pOpts > OPTPROC_EMIT_LIMIT)
  83. pOpts->pUsageProc(pOpts, EXIT_FAILURE);
  84. }
  85. /*=export_func optionNumericVal
  86. * private:
  87. *
  88. * what: process an option with a numeric value.
  89. * arg: + tOptions * + opts + program options descriptor +
  90. * arg: + tOptDesc * + od + the descriptor for this arg +
  91. *
  92. * doc:
  93. * Decipher a numeric value.
  94. =*/
  95. void
  96. optionNumericVal(tOptions * opts, tOptDesc * od)
  97. {
  98. char * pz;
  99. long val;
  100. /*
  101. * Guard against all the different ways this procedure might get invoked
  102. * when there is no string argument provided.
  103. */
  104. if (INQUERY_CALL(opts, od) || (od->optArg.argString == NULL))
  105. return;
  106. /*
  107. * Numeric options may have a range associated with it.
  108. * If it does, the usage procedure requests that it be
  109. * emitted by passing a NULL od pointer. Also bail out
  110. * if there is no option argument or if we are being reset.
  111. */
  112. if ( (od == NULL)
  113. || (od->optArg.argString == NULL)
  114. || ((od->fOptState & OPTST_RESET) != 0)
  115. || (opts <= OPTPROC_EMIT_LIMIT))
  116. return;
  117. errno = 0;
  118. val = strtol(od->optArg.argString, &pz, 0);
  119. if ((pz == od->optArg.argString) || (errno != 0))
  120. goto bad_number;
  121. if ((od->fOptState & OPTST_SCALED_NUM) != 0)
  122. switch (*(pz++)) {
  123. case NUL: pz--; break;
  124. case 't': val *= 1000; /* FALLTHROUGH */
  125. case 'g': val *= 1000; /* FALLTHROUGH */
  126. case 'm': val *= 1000; /* FALLTHROUGH */
  127. case 'k': val *= 1000; break;
  128. case 'T': val *= 1024; /* FALLTHROUGH */
  129. case 'G': val *= 1024; /* FALLTHROUGH */
  130. case 'M': val *= 1024; /* FALLTHROUGH */
  131. case 'K': val *= 1024; break;
  132. default: goto bad_number;
  133. }
  134. if (*pz != NUL)
  135. goto bad_number;
  136. if (od->fOptState & OPTST_ALLOC_ARG) {
  137. AGFREE(od->optArg.argString);
  138. od->fOptState &= ~OPTST_ALLOC_ARG;
  139. }
  140. od->optArg.argInt = val;
  141. return;
  142. bad_number:
  143. fprintf( stderr, zNotNumber, opts->pzProgName, od->optArg.argString );
  144. if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
  145. (*(opts->pUsageProc))(opts, EXIT_FAILURE);
  146. errno = EINVAL;
  147. od->optArg.argInt = ~0;
  148. }
  149. /** @}
  150. *
  151. * Local Variables:
  152. * mode: C
  153. * c-file-style: "stroustrup"
  154. * indent-tabs-mode: nil
  155. * End:
  156. * end of autoopts/numeric.c */