summaryrefslogtreecommitdiff
path: root/base/str.cc
diff options
context:
space:
mode:
authorNathan Binkert <binkertn@umich.edu>2003-10-31 18:27:17 -0500
committerNathan Binkert <binkertn@umich.edu>2003-10-31 18:27:17 -0500
commit5341e1aa9e3562d5217f3db87ca77238bf63f93e (patch)
treeb161a2c80994b44fe28ea0184b1cf73837288fcc /base/str.cc
parent8835aae3e3a4a4830b8cb03a7eefaa429ff63173 (diff)
downloadgem5-5341e1aa9e3562d5217f3db87ca77238bf63f93e.tar.xz
Make the to_number function work better.
base/str.cc: Make some fixes for the to_number function. Fix overflow calculation for maximum decimal value. (Note: minimum decimal value for signed numbers does not work correctly, e.g. it will overflow on -128 for a signed char though -127 will work) Fix overflow calculation for hex values being converted into signed types Fix up the debugging stuff a little to make sure the values are always printed as numbers. test/strnumtest.cc: using namespace std for g++ 3 --HG-- extra : convert_revision : b00bb1296c85c3d64d8864283c9374e1563bfa31
Diffstat (limited to 'base/str.cc')
-rw-r--r--base/str.cc30
1 files changed, 20 insertions, 10 deletions
diff --git a/base/str.cc b/base/str.cc
index 9c3964ce3..5ba23b55f 100644
--- a/base/str.cc
+++ b/base/str.cc
@@ -74,25 +74,31 @@ tokenize(vector<string>& v, const string &s, char token, bool ignore)
v.push_back(s.substr(first));
}
+/**
+ * @todo This function will not handle the smallest negative decimal
+ * value for a signed type
+ */
+
template <class T>
inline bool
__to_number(string value, T &retval)
{
static const T maxnum = ((T)-1);
static const bool sign = maxnum < 0;
- static const T hexmax = maxnum & (((T)1 << (sizeof(T) * 8 - 4)) - 1);
- static const T octmax = maxnum & (((T)1 << (sizeof(T) * 8 - 3)) - 1);
+ static const int bits = sizeof(T) * 8;
+ static const T hexmax = maxnum & (((T)1 << (bits - 4 - sign)) - 1);
+ static const T octmax = maxnum & (((T)1 << (bits - 3 - sign)) - 1);
static const T signmax =
- (sign) ? maxnum & (((T)1 << (sizeof(T) * 8 - 1)) - 1) : maxnum;
- static const T decmax = signmax / 10 - 1;
+ (sign) ? maxnum & (((T)1 << (bits - 1)) - 1) : maxnum;
+ static const T decmax = signmax / 10;
#if 0
- cout << "maxnum = 0x" << hex << maxnum << "\n"
- << "sign = 0x" << hex << sign << "\n"
- << "hexmax = 0x" << hex << hexmax << "\n"
- << "octmax = 0x" << hex << octmax << "\n"
- << "signmax = 0x" << hex << signmax << "\n"
- << "decmax = 0x" << hex << decmax << "\n";
+ cout << "maxnum = 0x" << hex << (unsigned long long)maxnum << "\n"
+ << "sign = 0x" << hex << (unsigned long long)sign << "\n"
+ << "hexmax = 0x" << hex << (unsigned long long)hexmax << "\n"
+ << "octmax = 0x" << hex << (unsigned long long)octmax << "\n"
+ << "signmax = 0x" << hex << (unsigned long long)signmax << "\n"
+ << "decmax = 0x" << hex << (unsigned long long)decmax << "\n";
#endif
eat_white(value);
@@ -180,8 +186,10 @@ __to_number(string value, T &retval)
goto multiply;
if (retval > decmax) return false;
+ bool atmax = retval == decmax;
retval *= 10;
retval += c - '0';
+ if (atmax && retval < decmax) return false;
if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1))))
return false;
}
@@ -190,8 +198,10 @@ __to_number(string value, T &retval)
if (IsDec(c)) {
if (retval > decmax) return false;
+ bool atmax = retval == decmax;
retval *= 10;
retval += c - '0';
+ if (atmax && retval < decmax) return false;
if (sign && negative) {
if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) &&
retval >= (T)-signmax)