diff options
author | Bernard Normier <bernard@zeroc.com> | 2005-04-18 16:19:51 +0000 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2005-04-18 16:19:51 +0000 |
commit | 1281ffa519e90550715d77c7548d38205072a10e (patch) | |
tree | 5ac39a746740cdacde8138cf8d15dc90746eaa4d | |
parent | Fix (diff) | |
download | ice-1281ffa519e90550715d77c7548d38205072a10e.tar.bz2 ice-1281ffa519e90550715d77c7548d38205072a10e.tar.xz ice-1281ffa519e90550715d77c7548d38205072a10e.zip |
Fixed bug #80: removed Int64Min / Int64Max
-rw-r--r-- | cpp/include/IceUtil/Config.h | 46 | ||||
-rw-r--r-- | cpp/include/IceUtil/InputUtil.h | 27 | ||||
-rw-r--r-- | cpp/src/FreezeScript/DumpDescriptors.cpp | 3 | ||||
-rw-r--r-- | cpp/src/FreezeScript/Scanner.l | 5 | ||||
-rw-r--r-- | cpp/src/FreezeScript/TransformVisitor.cpp | 3 | ||||
-rw-r--r-- | cpp/src/FreezeScript/Transformer.cpp | 3 | ||||
-rw-r--r-- | cpp/src/IceUtil/InputUtil.cpp | 155 | ||||
-rw-r--r-- | cpp/src/Slice/PythonUtil.cpp | 3 | ||||
-rw-r--r-- | cpp/src/Slice/Scanner.l | 5 | ||||
-rw-r--r-- | cpp/test/IceUtil/inputUtil/Client.cpp | 156 |
10 files changed, 108 insertions, 298 deletions
diff --git a/cpp/include/IceUtil/Config.h b/cpp/include/IceUtil/Config.h index 728e6b5c0c4..69bf3eb360d 100644 --- a/cpp/include/IceUtil/Config.h +++ b/cpp/include/IceUtil/Config.h @@ -121,19 +121,6 @@ # pragma warning( disable : 4275 ) // ...: decorated name length exceeded, name was truncated # pragma warning( disable : 4503 ) - -#elif (defined(__sun) && defined(__sparc)) || (defined(__hpux)) -# include <inttypes.h> -#else -// -// The ISO C99 standard specifies that in C++ implementations the -// macros for minimum/maximum integer values should only be defined if -// explicitly requested with __STDC_LIMIT_MACROS. -// -# ifndef __STDC_LIMIT_MACROS -# define __STDC_LIMIT_MACROS -# endif -# include <stdint.h> #endif // @@ -181,45 +168,23 @@ private: }; // -// Some definitions for 64-bit integers. +// Int64 typedef // #if defined(_MSC_VER) - typedef __int64 Int64; -const Int64 Int64Min = -9223372036854775808i64; -const Int64 Int64Max = 9223372036854775807i64; - -#elif defined(__SUNPRO_CC) - +#else # if defined(ICE_64) typedef long Int64; -const Int64 Int64Min = -0x7fffffffffffffffL-1L; -const Int64 Int64Max = 0x7fffffffffffffffL; # else typedef long long Int64; -const Int64 Int64Min = -0x7fffffffffffffffLL-1LL; -const Int64 Int64Max = 0x7fffffffffffffffLL; # endif +#endif -#else +} // -// Assumes ISO C99 types +// ICE_INT64: macro for Int64 litteral values // -typedef int64_t Int64; -# ifdef INT64_MIN -const Int64 Int64Min = INT64_MIN; -# else -const Int64 Int64Min = -0x7fffffffffffffffLL-1LL; -# endif -# ifdef INT64_MAX -const Int64 Int64Max = INT64_MAX; -# else -const Int64 Int64Max = 0x7fffffffffffffffLL; -# endif - -#endif - #if defined(_MSC_VER) # define ICE_INT64(n) n##i64 #elif defined(__HP_aCC) @@ -230,7 +195,6 @@ const Int64 Int64Max = 0x7fffffffffffffffLL; # define ICE_INT64(n) n##LL #endif -} // // The Ice version. diff --git a/cpp/include/IceUtil/InputUtil.h b/cpp/include/IceUtil/InputUtil.h index 7a650ef0ae9..32c888a95d9 100644 --- a/cpp/include/IceUtil/InputUtil.h +++ b/cpp/include/IceUtil/InputUtil.h @@ -12,24 +12,22 @@ #include <IceUtil/Config.h> #include <string> -#include <limits.h> namespace IceUtil { // -// strToInt64() is drop-in replacement for UNIX strtoll() +// Portable strtoll/_strtoi64 // ICE_UTIL_API Int64 strToInt64(const char*, char**, int); // // stringToInt64 converts a string into a signed 64-bit integer. -// -// bool stringToInt64(const std::string& stringToParse, Int64& result, std::string::size_type& pos); +// It's a simple wrapper around strToInt64. // // Semantics: // -// - Ignore leading and trailing whitespace +// - Ignore leading whitespace // // - If the string starts with '0', parse as octal // @@ -38,26 +36,11 @@ ICE_UTIL_API Int64 strToInt64(const char*, char**, int); // - Otherwise, parse as decimal // // - return value == true indicates a successful conversion and result contains the converted value -// -// - if pos == string::npos, there are no trailing non-whitespace characters following the converted string -// -// - if pos != string::npos, there are trailing non-whitespace characters following the converted string; -// pos indicates the first such character -// // - return value == false indicates an unsuccessful conversion: -// // - result == 0 indicates that no digits were available for conversion +// - result < 0 or result > 0 indicate underflow or overflow. // -// - result == INT64MIN or result == INT64MAX indicate underflow or overflow. -// -// - if pos == string::npos, the string did not contain trailing non-whitespace characters -// -// - if pos != string::npos, the string contained trailing non-whitespace characters following the -// digits and pos indicates the first such character. (Note that all digits up to the first -// non-digit, non-whitespace character are consumed, regardless of how far into the digit string -// an overflow is detected.) -// -ICE_UTIL_API bool stringToInt64(const std::string&, Int64&, std::string::size_type&); +ICE_UTIL_API bool stringToInt64(const std::string&, Int64&); } diff --git a/cpp/src/FreezeScript/DumpDescriptors.cpp b/cpp/src/FreezeScript/DumpDescriptors.cpp index 0cb2d0e055e..6c815f4eaa9 100644 --- a/cpp/src/FreezeScript/DumpDescriptors.cpp +++ b/cpp/src/FreezeScript/DumpDescriptors.cpp @@ -1571,9 +1571,8 @@ FreezeScript::SymbolTableI::getConstantValue(const string& name) const case Slice::Builtin::KindInt: case Slice::Builtin::KindLong: { - string::size_type end; Ice::Long n; - if(!IceUtil::stringToInt64(value, n, end)) + if(!IceUtil::stringToInt64(value, n)) { assert(false); } diff --git a/cpp/src/FreezeScript/Scanner.l b/cpp/src/FreezeScript/Scanner.l index 22b23fe4c59..203841fba05 100644 --- a/cpp/src/FreezeScript/Scanner.l +++ b/cpp/src/FreezeScript/Scanner.l @@ -122,10 +122,9 @@ floating_literal (({fractional_constant}{exponent_part}?)|((\+|-)?[[:digit:]]+{e {integer_constant} { IntegerTokPtr itp = new IntegerTok; *yylvalp = itp; - errno = 0; - itp->v = IceUtil::strToInt64(yytext, 0, 0); - if(errno == ERANGE && (itp->v == IceUtil::Int64Min || itp->v == IceUtil::Int64Max)) + if(!IceUtil::stringToInt64(string(yytext), itp->v)) { + assert(itp->v != 0); string msg = "integer constant `"; msg += yytext; msg += "' out of range"; diff --git a/cpp/src/FreezeScript/TransformVisitor.cpp b/cpp/src/FreezeScript/TransformVisitor.cpp index 45dca260c89..15772e6698b 100644 --- a/cpp/src/FreezeScript/TransformVisitor.cpp +++ b/cpp/src/FreezeScript/TransformVisitor.cpp @@ -75,9 +75,8 @@ FreezeScript::TransformVisitor::visitInteger(const IntegerDataPtr& dest) if(s) { string str = s->getValue(); - string::size_type pos; Ice::Long value; - if(IceUtil::stringToInt64(str, value, pos)) + if(IceUtil::stringToInt64(str, value)) { dest->setValue(value, false); } diff --git a/cpp/src/FreezeScript/Transformer.cpp b/cpp/src/FreezeScript/Transformer.cpp index c85cc3f9e10..69a44669407 100644 --- a/cpp/src/FreezeScript/Transformer.cpp +++ b/cpp/src/FreezeScript/Transformer.cpp @@ -2334,9 +2334,8 @@ FreezeScript::SymbolTableI::getConstantValue(const string& name) const case Slice::Builtin::KindInt: case Slice::Builtin::KindLong: { - string::size_type end; Ice::Long n; - if(!IceUtil::stringToInt64(value, n, end)) + if(!IceUtil::stringToInt64(value, n)) { assert(false); } diff --git a/cpp/src/IceUtil/InputUtil.cpp b/cpp/src/IceUtil/InputUtil.cpp index 06ace23ba51..1ec040a9def 100644 --- a/cpp/src/IceUtil/InputUtil.cpp +++ b/cpp/src/IceUtil/InputUtil.cpp @@ -13,138 +13,15 @@ using namespace std; -static const string allDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -// -// Table to convert ASCII digits/letters into their value (100 for unused slots) -// -static const char digitVal[] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // '0' - '9' - 100, 100, 100, 100, 100, 100, 100, // punctuation - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, // 'A' - 'J' - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, // 'K' - 'T' - 30, 31, 32, 33, 34, 35 // 'U' - 'Z' -}; namespace IceUtil { -// -// strToInt64 emulates strtoll() for Windows -// - Int64 strToInt64(const char* s, char** endptr, int base) { #if defined(_WIN32) - // - // Assume nothing will be there to convert for now - // - if(endptr) - { - *endptr = const_cast<char *>(s); - } - - // - // Skip leading whitespace - // - while(*s && isspace(*s)) - { - ++s; - } - - // - // Check for sign - // - int sign = 1; - if(*s == '+') - { - ++s; - } - else if(*s == '-') - { - sign = -1; - ++s; - } - - // - // Check that base is valid - // - if(base == 0) - { - if(*s == '0') - { - base = 8; - if(*++s == 'x' || *s == 'X') - { - base = 16; - ++s; - } - } - else - { - base = 10; - } - } - else if(base < 2 || base > 36) - { - errno = EINVAL; - return 0; - } - - // - // Check that we have something left to parse - // - if(*s == '/0') - { - return 0; - } - - Int64 result = 0; - bool overflow = false; - const string validDigits(allDigits.begin(), allDigits.begin() + base); - while(*s && validDigits.find_first_of(toupper(*s)) != validDigits.npos) - { - if(!overflow) - { - int digit = digitVal[toupper(*s) - '0']; - assert(digit != 100); - if(result < Int64Max / base) - { - result *= base; - result += digit; - } - else if((digit <= Int64Max % base) || (sign == -1 && digit == Int64Max % base + 1)) - { - result *= base; - result += digit; - } - else - { - overflow = true; - result = sign == -1 ? Int64Min : Int64Max; - } - } - ++s; - } - - if(overflow) - { - errno = ERANGE; - } - else - { - result *= sign; - } - - if(endptr) - { - *endptr = const_cast<char *>(s); - } - - return result; - + return _strtoi64(s, endptr, base); #elif defined(ICE_64) return strtol(s, endptr, base); #elif defined(__hpux) @@ -155,33 +32,13 @@ strToInt64(const char* s, char** endptr, int base) } bool -stringToInt64(const string& stringToParse, Int64& result, string::size_type& pos) +stringToInt64(const string& s, Int64& result) { - string::const_iterator i = stringToParse.begin(); - while(i != stringToParse.end() && isspace(*i)) - { - ++i; - } - if(i == stringToParse.end()) // String empty or nothing but whitespace - { - result = 0; - pos = string::npos; - return false; - } - string::const_reverse_iterator j = stringToParse.rbegin(); - while(isspace(*j)) - { - ++j; - } // j now points at last non-whitespace char - - string nonWhite(i, j.base()); // nonWhite has trailing whitespace stripped - + const char* start = s.c_str(); + char* end = 0; errno = 0; - const char* startp = nonWhite.c_str(); - char* endp; - result = strToInt64(startp, &endp, 0); - pos = *endp == '\0' ? string::npos : (i - stringToParse.begin()) + (endp - startp); - return startp != endp && errno != ERANGE && errno != EINVAL; + result = strToInt64(start, &end, 0); + return (errno == 0 && start != end); } } diff --git a/cpp/src/Slice/PythonUtil.cpp b/cpp/src/Slice/PythonUtil.cpp index 87bc16b3eab..6f4beebf727 100644 --- a/cpp/src/Slice/PythonUtil.cpp +++ b/cpp/src/Slice/PythonUtil.cpp @@ -1235,8 +1235,7 @@ Slice::Python::CodeVisitor::visitConst(const ConstPtr& p) case Slice::Builtin::KindLong: { IceUtil::Int64 l; - string::size_type pos; - IceUtil::stringToInt64(value, l, pos); + IceUtil::stringToInt64(value, l); // // The platform's 'long' type may not be 64 bits, so we store 64-bit // values as a string. diff --git a/cpp/src/Slice/Scanner.l b/cpp/src/Slice/Scanner.l index 561575ff044..101d87e108a 100644 --- a/cpp/src/Slice/Scanner.l +++ b/cpp/src/Slice/Scanner.l @@ -318,10 +318,9 @@ floating_literal (({fractional_constant}{exponent_part}?)|((\+|-)?[[:digit:]]+{e {integer_constant} { IntegerTokPtr itp = new IntegerTok; *yylvalp = itp; - errno = 0; - itp->v = IceUtil::strToInt64(yytext, 0, 0); - if(errno == ERANGE && (itp->v == IceUtil::Int64Min || itp->v == IceUtil::Int64Max)) + if(!IceUtil::stringToInt64(string(yytext), itp->v)) { + assert(itp->v != 0); string msg = "integer constant `"; msg += yytext; msg += "' out of range"; diff --git a/cpp/test/IceUtil/inputUtil/Client.cpp b/cpp/test/IceUtil/inputUtil/Client.cpp index 5f57b734087..12c337ec47f 100644 --- a/cpp/test/IceUtil/inputUtil/Client.cpp +++ b/cpp/test/IceUtil/inputUtil/Client.cpp @@ -16,6 +16,19 @@ using namespace std; #define WS " \f\n\r\t\v" +#if defined(_MSC_VER) +const Int64 Int64Min = -9223372036854775808i64; +const Int64 Int64Max = 9223372036854775807i64; +#else +# if defined(ICE_64) +const Int64 Int64Min = -0x7fffffffffffffffL-1L; +const Int64 Int64Max = 0x7fffffffffffffffL; +# else +const Int64 Int64Min = -0x7fffffffffffffffLL-1LL; +const Int64 Int64Max = 0x7fffffffffffffffLL; +# endif +#endif + int main(int, char**) { @@ -23,78 +36,77 @@ main(int, char**) bool b; Int64 result; - string::size_type pos; - - b = stringToInt64("", result, pos); - test(!b && result == 0 && pos == string::npos); - b = stringToInt64(WS, result, pos); - test(!b && result == 0 && pos == string::npos); - - b = stringToInt64("123", result, pos); - test(b && result == 123 && pos == string::npos); - b = stringToInt64("+123", result, pos); - test(b && result == 123 && pos == string::npos); - b = stringToInt64("-123", result, pos); - test(b && result == -123 && pos == string::npos); - - b = stringToInt64("0123", result, pos); - test(b && result == 83 && pos == string::npos); - b = stringToInt64("+0123", result, pos); - test(b && result == 83 && pos == string::npos); - b = stringToInt64("-0123", result, pos); - test(b && result == -83 && pos == string::npos); - - b = stringToInt64("0x123", result, pos); - test(b && result == 291 && pos == string::npos); - b = stringToInt64("+0x123", result, pos); - test(b && result == 291 && pos == string::npos); - b = stringToInt64("-0x123", result, pos); - test(b && result == -291 && pos == string::npos); - - b = stringToInt64(WS "123", result, pos); - test(b && result == 123 && pos == string::npos); - b = stringToInt64("123" WS, result, pos); - test(b && result == 123 && pos == string::npos); - b = stringToInt64(WS "123" WS, result, pos); - test(b && result == 123 && pos == string::npos); - - b = stringToInt64("123Q", result, pos); - test(b && result == 123 && pos == 3); - b = stringToInt64(" 123Q", result, pos); - test(b && result == 123 && pos == 4); - b = stringToInt64(" 123Q ", result, pos); - test(b && result == 123 && pos == 4); - b = stringToInt64(" 123 Q", result, pos); - test(b && result == 123 && pos == 4); - - b = stringToInt64("Q", result, pos); - test(!b && result == 0 && pos == 0); - b = stringToInt64(" Q", result, pos); - test(!b && result == 0 && pos == 1); - - b = stringToInt64("-9223372036854775807", result, pos); - test(b && result == ICE_INT64(-9223372036854775807) && pos == string::npos); - b = stringToInt64("-9223372036854775808", result, pos); - test(b && result == Int64Min && pos == string::npos); - b = stringToInt64("-9223372036854775809", result, pos); - test(!b && result == Int64Min && pos == string::npos); - - b = stringToInt64("9223372036854775806", result, pos); - test(b && result == ICE_INT64(9223372036854775806) && pos == string::npos); - b = stringToInt64("9223372036854775807", result, pos); - test(b && result == Int64Max && pos == string::npos); - b = stringToInt64("9223372036854775808", result, pos); - test(!b && result == Int64Max && pos == string::npos); - - b = stringToInt64("-9223372036854775807Q", result, pos); - test(b && result == ICE_INT64(-9223372036854775807) && pos == 20); - b = stringToInt64("-9223372036854775808Q", result, pos); - test(b && result == Int64Min && pos == 20); - b = stringToInt64("-9223372036854775809Q", result, pos); - test(!b && result == Int64Min && pos == 20); - - b = stringToInt64("-9223372036854775809999Q", result, pos); - test(!b && result == Int64Min && pos == 23); + + b = stringToInt64("", result); + test(!b && result == 0); + b = stringToInt64(WS, result); + test(!b && result == 0); + + b = stringToInt64("123", result); + test(b && result == 123); + b = stringToInt64("+123", result); + test(b && result == 123); + b = stringToInt64("-123", result); + test(b && result == -123); + + b = stringToInt64("0123", result); + test(b && result == 83); + b = stringToInt64("+0123", result); + test(b && result == 83); + b = stringToInt64("-0123", result); + test(b && result == -83); + + b = stringToInt64("0x123", result); + test(b && result == 291); + b = stringToInt64("+0x123", result); + test(b && result == 291); + b = stringToInt64("-0x123", result); + test(b && result == -291); + + b = stringToInt64(WS "123", result); + test(b && result == 123); + b = stringToInt64("123" WS, result); + test(b && result == 123); + b = stringToInt64(WS "123" WS, result); + test(b && result == 123); + + b = stringToInt64("123Q", result); + test(b && result == 123); + b = stringToInt64(" 123Q", result); + test(b && result == 123); + b = stringToInt64(" 123Q ", result); + test(b && result == 123); + b = stringToInt64(" 123 Q", result); + test(b && result == 123); + + b = stringToInt64("Q", result); + test(!b && result == 0); + b = stringToInt64(" Q", result); + test(!b && result == 0); + + b = stringToInt64("-9223372036854775807", result); + test(b && result == ICE_INT64(-9223372036854775807)); + b = stringToInt64("-9223372036854775808", result); + test(b && result == Int64Min); + b = stringToInt64("-9223372036854775809", result); + test(!b && result < 0); + + b = stringToInt64("9223372036854775806", result); + test(b && result == ICE_INT64(9223372036854775806)); + b = stringToInt64("9223372036854775807", result); + test(b && result == Int64Max); + b = stringToInt64("9223372036854775808", result); + test(!b && result > 0); + + b = stringToInt64("-9223372036854775807Q", result); + test(b && result == ICE_INT64(-9223372036854775807)); + b = stringToInt64("-9223372036854775808Q", result); + test(b && result == Int64Min); + b = stringToInt64("-9223372036854775809Q", result); + test(!b && result < 0); + + b = stringToInt64("-9223372036854775809999Q", result); + test(!b && result < 0); cout << "ok" << endl; |