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)) {