summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2005-04-18 16:19:51 +0000
committerBernard Normier <bernard@zeroc.com>2005-04-18 16:19:51 +0000
commit1281ffa519e90550715d77c7548d38205072a10e (patch)
tree5ac39a746740cdacde8138cf8d15dc90746eaa4d /cpp
parentFix (diff)
downloadice-1281ffa519e90550715d77c7548d38205072a10e.tar.bz2
ice-1281ffa519e90550715d77c7548d38205072a10e.tar.xz
ice-1281ffa519e90550715d77c7548d38205072a10e.zip
Fixed bug #80: removed Int64Min / Int64Max
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/IceUtil/Config.h46
-rw-r--r--cpp/include/IceUtil/InputUtil.h27
-rw-r--r--cpp/src/FreezeScript/DumpDescriptors.cpp3
-rw-r--r--cpp/src/FreezeScript/Scanner.l5
-rw-r--r--cpp/src/FreezeScript/TransformVisitor.cpp3
-rw-r--r--cpp/src/FreezeScript/Transformer.cpp3
-rw-r--r--cpp/src/IceUtil/InputUtil.cpp155
-rw-r--r--cpp/src/Slice/PythonUtil.cpp3
-rw-r--r--cpp/src/Slice/Scanner.l5
-rw-r--r--cpp/test/IceUtil/inputUtil/Client.cpp156
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;