numeric.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * $Id: numeric.c,v 4.19 2008/11/02 18:51:26 bkorb Exp $
  3. * Time-stamp: "2008-11-01 14:28:56 bkorb"
  4. *
  5. * This file is part of AutoOpts, a companion to AutoGen.
  6. * AutoOpts is free software.
  7. * AutoOpts is copyright (c) 1992-2008 by Bruce Korb - all rights reserved
  8. * AutoOpts is copyright (c) 1992-2008 by Bruce Korb - all rights reserved
  9. *
  10. * AutoOpts is available under any one of two licenses. The license
  11. * in use must be one of these two and the choice is under the control
  12. * of the user of the license.
  13. *
  14. * The GNU Lesser General Public License, version 3 or later
  15. * See the files "COPYING.lgplv3" and "COPYING.gplv3"
  16. *
  17. * The Modified Berkeley Software Distribution License
  18. * See the file "COPYING.mbsd"
  19. *
  20. * These files have the following md5sums:
  21. *
  22. * 239588c55c22c60ffe159946a760a33e pkg/libopts/COPYING.gplv3
  23. * fa82ca978890795162346e661b47161a pkg/libopts/COPYING.lgplv3
  24. * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
  25. */
  26. /*=export_func optionShowRange
  27. * private:
  28. *
  29. * what:
  30. * arg: + tOptions* + pOpts + program options descriptor +
  31. * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
  32. * arg: + void * + rng_table + the value range tables +
  33. * arg: + int + rng_count + the number of entries +
  34. *
  35. * doc:
  36. * Show information about a numeric option with range constraints.
  37. =*/
  38. void
  39. optionShowRange(tOptions* pOpts, tOptDesc* pOD, void * rng_table, int rng_ct)
  40. {
  41. const struct {long const rmin, rmax;} * rng = rng_table;
  42. char const * pz_indent =
  43. (pOpts != OPTPROC_EMIT_USAGE) ? "\t" : "\t\t\t\t ";
  44. if ((pOpts == OPTPROC_EMIT_USAGE) || (pOpts > OPTPROC_EMIT_LIMIT)) {
  45. char const * lie_in_range = zRangeLie;
  46. if (pOpts > OPTPROC_EMIT_LIMIT) {
  47. fprintf(option_usage_fp, zRangeErr,
  48. pOpts->pzProgName, pOD->pz_Name, pOD->optArg.argString);
  49. fprintf(option_usage_fp, "The %s option:\n", pOD->pz_Name);
  50. lie_in_range = zRangeBadLie;
  51. pz_indent = "";
  52. }
  53. if (pOD->fOptState & OPTST_SCALED_NUM)
  54. fprintf(option_usage_fp, zRangeScaled, pz_indent);
  55. if (rng_ct > 1)
  56. fprintf(option_usage_fp, lie_in_range, pz_indent);
  57. else {
  58. fprintf(option_usage_fp, zRangeOnly, pz_indent);
  59. }
  60. for (;;) {
  61. if (rng->rmax == LONG_MIN)
  62. fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin);
  63. else if (rng->rmin == LONG_MIN)
  64. fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax);
  65. else if (rng->rmax == LONG_MAX)
  66. fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin);
  67. else
  68. fprintf(option_usage_fp, zRange, pz_indent, rng->rmin,
  69. rng->rmax);
  70. if (--rng_ct <= 0) {
  71. fputc('\n', option_usage_fp);
  72. break;
  73. }
  74. fputs(zRangeOr, option_usage_fp);
  75. rng++;
  76. }
  77. if (pOpts > OPTPROC_EMIT_LIMIT)
  78. pOpts->pUsageProc(pOpts, EXIT_FAILURE);
  79. }
  80. }
  81. /*=export_func optionNumericVal
  82. * private:
  83. *
  84. * what: process an option with a numeric value.
  85. * arg: + tOptions* + pOpts + program options descriptor +
  86. * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
  87. *
  88. * doc:
  89. * Decipher a numeric value.
  90. =*/
  91. void
  92. optionNumericVal(tOptions* pOpts, tOptDesc* pOD )
  93. {
  94. char* pz;
  95. long val;
  96. if ((pOD->fOptState & OPTST_RESET) != 0)
  97. return;
  98. /*
  99. * Numeric options may have a range associated with it.
  100. * If it does, the usage procedure requests that it be
  101. * emitted by passing a NULL pOD pointer.
  102. */
  103. if ((pOD == NULL) || (pOD->optArg.argString == NULL))
  104. return;
  105. errno = 0;
  106. val = strtol(pOD->optArg.argString, &pz, 0);
  107. if ((pz == pOD->optArg.argString) || (errno != 0))
  108. goto bad_number;
  109. if ((pOD->fOptState & OPTST_SCALED_NUM) != 0)
  110. switch (*(pz++)) {
  111. case '\0': pz--; break;
  112. case 't': val *= 1000;
  113. case 'g': val *= 1000;
  114. case 'm': val *= 1000;
  115. case 'k': val *= 1000; break;
  116. case 'T': val *= 1024;
  117. case 'G': val *= 1024;
  118. case 'M': val *= 1024;
  119. case 'K': val *= 1024; break;
  120. default: goto bad_number;
  121. }
  122. if (*pz != NUL)
  123. goto bad_number;
  124. if (pOD->fOptState & OPTST_ALLOC_ARG) {
  125. AGFREE(pOD->optArg.argString);
  126. pOD->fOptState &= ~OPTST_ALLOC_ARG;
  127. }
  128. pOD->optArg.argInt = val;
  129. return;
  130. bad_number:
  131. fprintf( stderr, zNotNumber, pOpts->pzProgName, pOD->optArg.argString );
  132. if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
  133. (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
  134. pOD->optArg.argInt = ~0;
  135. }
  136. /*
  137. * Local Variables:
  138. * mode: C
  139. * c-file-style: "stroustrup"
  140. * indent-tabs-mode: nil
  141. * End:
  142. * end of autoopts/numeric.c */