You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2006/11/28 21:53:33 UTC
svn commit: r480205 - /incubator/stdcxx/trunk/util/monetary.cpp
Author: sebor
Date: Tue Nov 28 12:53:33 2006
New Revision: 480205
URL: http://svn.apache.org/viewvc?view=rev&rev=480205
Log:
2006-11-28 Martin Sebor <se...@roguewave.com>
* monetary.cpp (process_monetary): Simplified the parsing of integer
values and checking their validity.
Modified:
incubator/stdcxx/trunk/util/monetary.cpp
Modified: incubator/stdcxx/trunk/util/monetary.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/monetary.cpp?view=diff&rev=480205&r1=480204&r2=480205
==============================================================================
--- incubator/stdcxx/trunk/util/monetary.cpp (original)
+++ incubator/stdcxx/trunk/util/monetary.cpp Tue Nov 28 12:53:33 2006
@@ -32,7 +32,8 @@
#include "scanner.h" // for scanner
#include <cassert> // for assert()
-#include <cstdlib> // for atoi()
+#include <climits> // for CHAR_MAX, CHAR_MIN
+#include <cstdlib> // for strtol()
#include <fstream> // for ofstream
#include <locale> // for money_base
@@ -44,12 +45,20 @@
{
issue_diag (I_STAGE, false, 0, "processing %s section\n", lc_name);
- // nexting level
+ // nesting level
int nesting_level = 0;
mon_def_found_ = true;
while ((next = scanner_.next_token ()).token != Scanner::tok_monetary) {
+
+ // set to point to the integer represented as an ordinary char
+ // corresponding to p_cs_precedes, p_sep_by_space, p_sign_posn,
+ // or one of the n_ (or int_ versions) of the same
+ char *pcharint = 0;
+
+ typedef unsigned char UChar;
+ long maxval = long (UChar (CHAR_MAX)); // maximum allowed value
switch (next.token) {
@@ -124,9 +133,8 @@
case Scanner::tok_mon_grouping:
mon_st_.mon_grouping.clear();
- while ((next = scanner_.next_token()).token
- != Scanner::tok_nl)
- mon_st_.mon_grouping += std::atoi(next.name.c_str());
+ while ((next = scanner_.next_token()).token != Scanner::tok_nl)
+ mon_st_.mon_grouping += std::strtol (next.name.c_str (), 0, 10);
break;
case Scanner::tok_positive_sign:
@@ -141,182 +149,94 @@
mon_st_.wnegative_sign = convert_wstring (next);
break;
- case Scanner::tok_int_frac_digits:
- mon_out_.frac_digits[1] =
- std::atoi(scanner_.next_token().name.c_str());
- //strtol(scanner_.next_token().name.c_str(), 0, 10);
+ case Scanner::tok_frac_digits:
+ pcharint = &mon_out_.frac_digits [0];
break;
- case Scanner::tok_frac_digits:
- mon_out_.frac_digits[0] =
- std::atoi(scanner_.next_token().name.c_str());
+ case Scanner::tok_int_frac_digits:
+ pcharint = &mon_out_.frac_digits [1 /* int'l */ ];
break;
case Scanner::tok_p_cs_precedes:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] == '0'
- || next.name[0] == '1')) {
- mon_out_.p_cs_precedes[0] = std::atoi(next.name.c_str());
- }
- else
- issue_diag (E_INVAL, true, &next,
- "%s is an invalid p_cs_precedes value\n",
- next.name.c_str());
+ maxval = 1;
+ pcharint = &mon_out_.p_cs_precedes [0];
break;
case Scanner::tok_p_sep_by_space:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] >= '0'
- && next.name[0] <= '2')) {
- mon_out_.p_sep_by_space[0] = std::atoi(next.name.c_str());
- }
- else
- issue_diag (E_INVAL, true, &next,
- "%s is an invalid p_sep_by_space value\n",
- next.name.c_str());
+ maxval = 2;
+ pcharint = &mon_out_.p_sep_by_space [0];
break;
case Scanner::tok_n_cs_precedes:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] == '0'
- || next.name[0] == '1')) {
- mon_out_.n_cs_precedes[0] = std::atoi(next.name.c_str());
- }
- else
- issue_diag (E_INVAL, true, &next,
- "%s is an invalid n_cs_precedes value\n",
- next.name.c_str());
+ maxval = 1;
+ pcharint = &mon_out_.n_cs_precedes [0];
break;
case Scanner::tok_n_sep_by_space:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] >= '0'
- && next.name[0] <= '2')) {
- mon_out_.n_sep_by_space[0] = std::atoi(next.name.c_str());
- }
- else
- issue_diag (E_INVAL, true, &next,
- "%s is an invalid n_sep_by_space value\n",
- next.name.c_str());
+ maxval = 2;
+ pcharint = &mon_out_.n_sep_by_space [0];
break;
case Scanner::tok_p_sign_posn:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] >= '0'
- && next.name[0] <= '4')) {
- mon_out_.p_sign_posn[0] = std::atoi(next.name.c_str());
- }
- else
- issue_diag (120, true, &next,
- "%s is an invalid p_sign_posn value\n",
- next.name.c_str());
+ maxval = 4;
+ pcharint = &mon_out_.p_sign_posn [0];
break;
case Scanner::tok_n_sign_posn:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] >= '0'
- && next.name[0] <= '4')) {
- mon_out_.n_sign_posn[0] = std::atoi(next.name.c_str());
- }
- else
- issue_diag (120, true, &next,
- "%s is an invalid n_sign_posn value\n",
- next.name.c_str());
+ maxval = 4;
+ pcharint = &mon_out_.n_sign_posn [0];
break;
case Scanner::tok_int_p_cs_precedes:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] == '0'
- || next.name[0] == '1')) {
- mon_out_.p_cs_precedes[1] = std::atoi(next.name.c_str());
- }
- else {
- if (!(next.name.size() == 2 && (next.name[0] == '-'
- && next.name[1] == '1')))
- issue_diag (E_INVAL, true, &next,
- "%s is an invalid int_p_cs_precedes value\n",
- next.name.c_str());
- }
+ maxval = 1;
+ pcharint = &mon_out_.p_cs_precedes [1 /* int'l */ ];
break;
case Scanner::tok_int_p_sep_by_space:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] >= '0'
- && next.name[0] <= '2')) {
- mon_out_.p_sep_by_space[1] = std::atoi(next.name.c_str());
- }
- else {
- if (!(next.name.size() == 2 && (next.name[0] == '-'
- && next.name[1] == '1')))
- issue_diag (E_INVAL, true, &next,
- "%s is a invalid int_p_sep_by_space value\n",
- next.name.c_str());
- }
+ maxval = 2;
+ pcharint = &mon_out_.p_sep_by_space [1 /* int'l */ ];
break;
case Scanner::tok_int_n_cs_precedes:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] == '0'
- || next.name[0] == '1')) {
- mon_out_.n_cs_precedes[1] = std::atoi(next.name.c_str());
- }
- else {
- if (!(next.name.size() == 2 && (next.name[0] == '-'
- && next.name[1] == '1')))
- issue_diag (E_INVAL, true, &next,
- "%s is an invalid int_n_cs_precedes value\n",
- next.name.c_str());
- }
+ maxval = 1;
+ pcharint = &mon_out_.n_cs_precedes [1 /* int'l */ ];
break;
case Scanner::tok_int_n_sep_by_space:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] >= '0'
- && next.name[0] <= '2')) {
- mon_out_.n_sep_by_space[1] = std::atoi(next.name.c_str());
- }
- else {
- if (!(next.name.size() == 2 && (next.name[0] == '-'
- && next.name[1] == '1')))
- issue_diag (124, true, &next,
- "%s is a invalid int_n_sep_by_space value\n",
- next.name.c_str());
- }
+ maxval = 2;
+ pcharint = &mon_out_.n_sep_by_space [1 /* int'l */ ];
break;
case Scanner::tok_int_p_sign_posn:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] >= '0'
- && next.name[0] <= '4')) {
- mon_out_.p_sign_posn[1] = std::atoi(next.name.c_str());
- }
- else {
- if (!(next.name.size() == 2 && (next.name[0] == '-'
- && next.name[1] == '1')))
- issue_diag (E_INVAL, true, &next,
- "%s is an invalid int_p_sign_posn value\n",
- next.name.c_str());
- }
+ maxval = 4;
+ pcharint = &mon_out_.p_sign_posn [1 /* int'l */ ];
break;
case Scanner::tok_int_n_sign_posn:
- next = scanner_.next_token();
- if (next.name.size() == 1 && (next.name[0] >= '0'
- && next.name[0] <= '4')) {
- mon_out_.n_sign_posn[1] = std::atoi(next.name.c_str());
- }
- else {
- if (!(next.name.size() == 2 && (next.name[0] == '-'
- && next.name[1] == '1')))
- issue_diag (E_INVAL, true, &next,
- "%s is an invalid int_n_sign_posn value\n",
- next.name.c_str());
- }
+ maxval = 4;
+ pcharint = &mon_out_.n_sign_posn [1 /* int'l */ ];
break;
default:
break;
+ }
+
+ if (pcharint) {
+ next = scanner_.next_token ();
+
+ char *end = 0;
+ const long val = std::strtol (next.name.c_str (), &end, 10);
+
+ if (next.name.empty () || *end || val < -1 || maxval < val) {
+ // report as errors values outside the permitted range
+ // (-1 indicates an unspecified value for a keyword)
+ issue_diag (E_INVAL, true, &next,
+ "expected integer in [0, %li], got: %s\n",
+ maxval, next.name.c_str ());
+ }
+ else
+ *pcharint = char (val);
}
}
}