Return-Path: Delivered-To: apmail-incubator-stdcxx-commits-archive@www.apache.org Received: (qmail 92323 invoked from network); 29 May 2007 00:26:13 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 29 May 2007 00:26:13 -0000 Received: (qmail 2023 invoked by uid 500); 29 May 2007 00:26:17 -0000 Delivered-To: apmail-incubator-stdcxx-commits-archive@incubator.apache.org Received: (qmail 2007 invoked by uid 500); 29 May 2007 00:26:17 -0000 Mailing-List: contact stdcxx-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-commits@incubator.apache.org Received: (qmail 1996 invoked by uid 99); 29 May 2007 00:26:17 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 28 May 2007 17:26:17 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 28 May 2007 17:26:12 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 184231A981A; Mon, 28 May 2007 17:25:52 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r542366 - /incubator/stdcxx/trunk/src/strtol.cpp Date: Tue, 29 May 2007 00:25:52 -0000 To: stdcxx-commits@incubator.apache.org From: sebor@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070529002552.184231A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 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)) {