31,34d30
< #include <cctype>
< #include <cstring>
< #include <iostream>
< #include <limits>
38d33
< #include "base/intmath.hh"
109,375d103
<
< /**
< * @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 = numeric_limits<T>::is_signed;
< static const int bits = numeric_limits<T>::digits;
< static const T hexmax = maxnum & (((T)1 << (bits - 4)) - 1);
< static const T octmax = maxnum & (((T)1 << (bits - 3)) - 1);
< static const T signmax = numeric_limits<T>::max();
< static const T decmax = signmax / 10;
<
< #if 0
< 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);
<
< bool negative = false;
< bool hex = false;
< bool oct = false;
< int last = value.size() - 1;
< retval = 0;
< int i = 0;
<
< char c = value[i];
< if (!isDec(c)) {
< if (c == '-' && sign)
< negative = true;
< else
< return false;
< }
< else {
< retval += c - '0';
< if (last == 0) return true;
< }
<
< if (c == '0')
< oct = true;
<
< c = value[++i];
< if (oct) {
< if (sign && negative)
< return false;
<
< if (!isOct(c)) {
< if (c == 'X' || c == 'x') {
< hex = true;
< oct = false;
< } else
< return false;
< }
< else
< retval += c - '0';
< } else if (!isDec(c))
< goto multiply;
< else {
< if (sign && negative && c == '0')
< return false;
<
< retval *= 10;
< retval += c - '0';
< if (last == 1) {
< if (sign && negative) retval = -retval;
< return true;
< }
< }
<
< if (hex) {
< if (last == 1)
< return false;
<
< for (i = 2; i <= last ; i++) {
< c = value[i];
< if (!isHex(c))
< return false;
<
< if (retval > hexmax) return false;
< retval *= 16;
< retval += hex2Int(c);
< }
< return true;
< } else if (oct) {
< for (i = 2; i <= last ; i++) {
< c = value[i];
< if (!isOct(c))
< return false;
<
< if (retval > octmax) return false;
< retval *= 8;
< retval += (c - '0');
< }
< return true;
< }
<
< for (i = 2; i < last ; i++) {
< c = value[i];
< if (!isDec(c))
< 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;
< }
<
< c = value[last];
< 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)
< return false;
< retval = -retval;
< }
< else
< if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1))))
< return false;
< return true;
< }
<
< multiply:
< signed long long mult = 1;
< T val;
< switch (c) {
< case 'k':
< case 'K':
< if (i != last) return false;
< mult = 1024;
< val = signmax / mult;
< break;
< case 'm':
< case 'M':
< if (i != last) return false;
< mult = 1024 * 1024;
< val = signmax / mult;
< break;
< case 'g':
< case 'G':
< if (i != last) return false;
< mult = 1024 * 1024 * 1024;
< val = signmax / mult;
< break;
< case 'e':
< case 'E':
< if (i >= last) return false;
<
< mult = 0;
< for (i++; i <= last; i++) {
< c = value[i];
< if (!isDec(c))
< return false;
<
< mult *= 10;
< mult += c - '0';
< }
<
< for (i = 0; i < mult; i++) {
< if (retval > signmax / 10)
< return false;
< retval *= 10;
< if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1))))
< return false;
< }
< if (sign && negative) {
< if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) &&
< retval >= (T)-signmax)
< return false;
< retval = -retval;
< }
< else
< if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1))))
< return false;
<
< return true;
<
< default:
< return false;
< }
<
< if (sign && negative)
< return false;
<
< if (mult > (unsigned long long)signmax)
< return false;
<
< if (retval > val)
< return false;
<
< retval *= mult;
<
< return true;
< }
<
< #define STN(type) \
< template<> \
< bool to_number<type>(const string &value, type &retval) \
< { return __to_number(value, retval); }
<
< STN(unsigned long long)
< STN(signed long long)
< STN(unsigned long)
< STN(signed long)
< STN(unsigned int)
< STN(signed int)
< STN(unsigned short)
< STN(signed short)
< STN(unsigned char)
< STN(signed char)
< STN(char)
<
< template<>
< bool to_number<bool>(const string &value, bool &retval)
< {
< string lowered = to_lower(value);
<
< if (value == "0") {
< retval = false;
< return true;
< }
<
< if (value == "1"){
< retval = true;
< return true;
< }
<
< if (lowered == "false") {
< retval = false;
< return true;
< }
<
< if (lowered == "true"){
< retval = true;
< return true;
< }
<
< if (lowered == "no") {
< retval = false;
< return true;
< }
<
< if (lowered == "yes"){
< retval = true;
< return true;
< }
<
< return false;
< }