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 2007/05/29 02:25:52 UTC
svn commit: r542366 - /incubator/stdcxx/trunk/src/strtol.cpp
Author: sebor
Date: Mon May 28 17:25:51 2007
New Revision: 542366
URL: http://svn.apache.org/viewvc?view=rev&rev=542366
Log:
2007-05-28 Martin Sebor <se...@roguewave.com>
STDCXX-402
* strtol.cpp (__rw_strtoul, __rw_strtol, __rw_strtoull, __rw_strtoll):
Asserted preconditions.
(LLong, ULLong): New convenience typedefs at namespace scope.
(__rw_strtoull, __rw_strtoll): Corrected off by one errors.
Modified:
incubator/stdcxx/trunk/src/strtol.cpp
Modified: incubator/stdcxx/trunk/src/strtol.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/src/strtol.cpp?view=diff&rev=542366&r1=542365&r2=542366
==============================================================================
--- incubator/stdcxx/trunk/src/strtol.cpp (original)
+++ incubator/stdcxx/trunk/src/strtol.cpp Mon May 28 17:25:51 2007
@@ -2,7 +2,7 @@
*
* strtol.cpp - definitions of __rw_strtol, __rw_strtoul, and other helpers
*
- * $Id: //stdlib/dev/source/stdlib/strtol.cpp#7 $
+ * $Id$
*
***************************************************************************
*
@@ -145,6 +145,8 @@
// SHift Left and OR: helper macro used by __rw_strtol
// to multiply a number by a power of 2 (SHL) and add
// another number less than the power (OR)
+//
+// IMPORTANT: each argument must be evaluated exactly once
#undef SHLOR
#define SHLOR(x, dig) (((x) << shift) | __rw_digit_map [UChar (dig)])
@@ -163,6 +165,8 @@
// MULtiply and ADD: helper macro used by __rw_strtol
+//
+// IMPORTANT: each argument must be evaluated exactly once
#undef MULADD
#define MULADD(x, dig) (((x) * base) + __rw_digit_map [UChar (dig)])
@@ -199,6 +203,8 @@
unsigned long res = __rw_digit_map [UChar (*nptr)];
+ _RWSTD_ASSERT (res < unsigned (base));
+
if (shift) {
// process subject sequence by shifting
@@ -245,6 +251,8 @@
const unsigned digit =
__rw_digit_map [UChar (*nptr)];
+ _RWSTD_ASSERT (digit < unsigned (base));
+
// check for overflow
const unsigned long save = res;
@@ -353,6 +361,8 @@
const unsigned digit = __rw_digit_map [UChar (*nptr)];
+ _RWSTD_ASSERT (digit < unsigned (base));
+
// check for overflow
if (maxres < res)
goto overflow;
@@ -395,6 +405,8 @@
unsigned long res = __rw_digit_map [UChar (*nptr)];
+ _RWSTD_ASSERT (res < unsigned (base));
+
if (shift) {
// process subject sequence by shifting
@@ -441,6 +453,8 @@
const unsigned digit =
__rw_digit_map [UChar (*nptr)];
+ _RWSTD_ASSERT (digit < unsigned (base));
+
// check for overflow
const unsigned long save = res;
@@ -550,6 +564,8 @@
const unsigned digit = __rw_digit_map [UChar (*nptr)];
+ _RWSTD_ASSERT (digit < unsigned (base));
+
// check for overflow
if (maxres < res)
goto overflow;
@@ -592,11 +608,17 @@
#ifdef _RWSTD_LONG_LONG
+
+// for convenience
+typedef _RWSTD_LONG_LONG LLong;
+typedef unsigned _RWSTD_LONG_LONG ULLong;
+
+
// using LLONG_SIZE instead of ULLONG_MAX in the preprocessor
// conditional below to work around a gcc 3.2 bug (PR #28595)
# if (_RWSTD_LONG_SIZE < _RWSTD_LLONG_SIZE)
-unsigned _RWSTD_LONG_LONG
+ULLong
__rw_strtoull (const char *nptr, int *errptr, int base)
{
_RWSTD_ASSERT (0 != nptr);
@@ -612,7 +634,9 @@
const int shift = __rw_base_bits [base];
- unsigned _RWSTD_LONG_LONG res = __rw_digit_map [UChar (*nptr)];
+ ULLong res = __rw_digit_map [UChar (*nptr)];
+
+ _RWSTD_ASSERT (res < unsigned (base));
if (shift) {
@@ -657,8 +681,10 @@
const unsigned digit =
__rw_digit_map [UChar (*nptr)];
+ _RWSTD_ASSERT (digit < unsigned (base));
+
// check for overflow
- const unsigned _RWSTD_LONG_LONG save = res;
+ const ULLong save = res;
res <<= shift;
@@ -687,9 +713,9 @@
// process subject sequence by multiplication
// unroll loop w/o overflow checking
- if (*++nptr) {
+ if (nptr [1]) {
// multiply by base and add second digit
- res = MULADD (res, *nptr);
+ res = MULADD (res, *++nptr);
// digits 3 through 6, inclusive
MULADD_4_DIGITS_BEGIN (res, nptr);
@@ -703,9 +729,9 @@
// digits 7 through 10, inclusive
MULADD_4_DIGITS_BEGIN (res, nptr);
- if (*++nptr) {
+ if (nptr [1]) {
// digit 11
- res = MULADD (res, *nptr);
+ res = MULADD (res, *++nptr);
if (base < 12) {
@@ -749,11 +775,12 @@
// close brackets
MULADD_4_DIGITS_END ();
- for (unsigned _RWSTD_LONG_LONG maxres = _RWSTD_ULLONG_MAX / base;
- *++nptr; ) {
+ for (ULLong maxres = _RWSTD_ULLONG_MAX / base; *++nptr; ) {
const unsigned digit = __rw_digit_map [UChar (*nptr)];
+ _RWSTD_ASSERT (digit < unsigned (base));
+
// check for overflow
if (maxres < res)
goto overflow;
@@ -778,7 +805,7 @@
}
-_RWSTD_LONG_LONG
+LLong
__rw_strtoll (const char *nptr, int *errptr, int base)
{
_RWSTD_ASSERT (0 != nptr);
@@ -794,7 +821,9 @@
const int shift = __rw_base_bits [base];
- unsigned _RWSTD_LONG_LONG res = __rw_digit_map [UChar (*nptr)];
+ ULLong res = __rw_digit_map [UChar (*nptr)];
+
+ _RWSTD_ASSERT (res < unsigned (base));
if (shift) {
@@ -839,8 +868,10 @@
const unsigned digit =
__rw_digit_map [UChar (*nptr)];
+ _RWSTD_ASSERT (digit < unsigned (base));
+
// check for overflow
- const unsigned _RWSTD_LONG_LONG save = res;
+ const ULLong save = res;
res <<= shift;
@@ -886,9 +917,9 @@
// digits 7 through 10, inclusive
MULADD_4_DIGITS_BEGIN (res, nptr);
- if (*++nptr) {
+ if (nptr [1]) {
// digit 11
- res = MULADD (res, *nptr);
+ res = MULADD (res, *++nptr);
if (base < 12) {
@@ -932,11 +963,12 @@
// close brackets
MULADD_4_DIGITS_END ();
- for (unsigned _RWSTD_LONG_LONG maxres =
- _RWSTD_ULLONG_MAX / base; *++nptr; ) {
+ for (ULLong maxres = _RWSTD_ULLONG_MAX / base; *++nptr; ) {
const unsigned digit = __rw_digit_map [UChar (*nptr)];
+ _RWSTD_ASSERT (digit < unsigned (base));
+
// check for overflow
if (maxres < res)
goto overflow;
@@ -951,15 +983,13 @@
}
}
- typedef unsigned _RWSTD_LONG_LONG ULLong;
-
if (neg) {
if (res > ULLong (_RWSTD_LLONG_MIN)) {
*errptr = ERANGE;
return _RWSTD_LLONG_MIN;
}
- return -_RWSTD_STATIC_CAST (_RWSTD_LONG_LONG, res);
+ return -LLong (res);
}
if (res > ULLong (_RWSTD_LLONG_MAX)) {