numeric.c 5.2 KB

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