str.cc (8902:75b524b64c28) | str.cc (10386:c81407818741) |
---|---|
1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 14 unchanged lines hidden (view full) --- 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Nathan Binkert 29 */ 30 | 1/* 2 * Copyright (c) 2001-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 14 unchanged lines hidden (view full) --- 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Nathan Binkert 29 */ 30 |
31#include <cctype> 32#include <cstring> 33#include <iostream> 34#include <limits> | |
35#include <string> 36#include <vector> 37 | 31#include <string> 32#include <vector> 33 |
38#include "base/intmath.hh" | |
39#include "base/str.hh" 40 41using namespace std; 42 43bool 44split_first(const string &s, string &lhs, string &rhs, char c) 45{ 46 string::size_type offset = s.find(c); --- 54 unchanged lines hidden (view full) --- 101 } else 102 first = last + 1; 103 104 last = s.find_first_of(token, first); 105 } 106 107 v.push_back(s.substr(first)); 108} | 34#include "base/str.hh" 35 36using namespace std; 37 38bool 39split_first(const string &s, string &lhs, string &rhs, char c) 40{ 41 string::size_type offset = s.find(c); --- 54 unchanged lines hidden (view full) --- 96 } else 97 first = last + 1; 98 99 last = s.find_first_of(token, first); 100 } 101 102 v.push_back(s.substr(first)); 103} |
109 110/** 111 * @todo This function will not handle the smallest negative decimal 112 * value for a signed type 113 */ 114 115template <class T> 116inline bool 117__to_number(string value, T &retval) 118{ 119 static const T maxnum = ((T)-1); 120 static const bool sign = numeric_limits<T>::is_signed; 121 static const int bits = numeric_limits<T>::digits; 122 static const T hexmax = maxnum & (((T)1 << (bits - 4)) - 1); 123 static const T octmax = maxnum & (((T)1 << (bits - 3)) - 1); 124 static const T signmax = numeric_limits<T>::max(); 125 static const T decmax = signmax / 10; 126 127#if 0 128 cout << "maxnum = 0x" << hex << (unsigned long long)maxnum << "\n" 129 << "sign = 0x" << hex << (unsigned long long)sign << "\n" 130 << "hexmax = 0x" << hex << (unsigned long long)hexmax << "\n" 131 << "octmax = 0x" << hex << (unsigned long long)octmax << "\n" 132 << "signmax = 0x" << hex << (unsigned long long)signmax << "\n" 133 << "decmax = 0x" << hex << (unsigned long long)decmax << "\n"; 134#endif 135 136 eat_white(value); 137 138 bool negative = false; 139 bool hex = false; 140 bool oct = false; 141 int last = value.size() - 1; 142 retval = 0; 143 int i = 0; 144 145 char c = value[i]; 146 if (!isDec(c)) { 147 if (c == '-' && sign) 148 negative = true; 149 else 150 return false; 151 } 152 else { 153 retval += c - '0'; 154 if (last == 0) return true; 155 } 156 157 if (c == '0') 158 oct = true; 159 160 c = value[++i]; 161 if (oct) { 162 if (sign && negative) 163 return false; 164 165 if (!isOct(c)) { 166 if (c == 'X' || c == 'x') { 167 hex = true; 168 oct = false; 169 } else 170 return false; 171 } 172 else 173 retval += c - '0'; 174 } else if (!isDec(c)) 175 goto multiply; 176 else { 177 if (sign && negative && c == '0') 178 return false; 179 180 retval *= 10; 181 retval += c - '0'; 182 if (last == 1) { 183 if (sign && negative) retval = -retval; 184 return true; 185 } 186 } 187 188 if (hex) { 189 if (last == 1) 190 return false; 191 192 for (i = 2; i <= last ; i++) { 193 c = value[i]; 194 if (!isHex(c)) 195 return false; 196 197 if (retval > hexmax) return false; 198 retval *= 16; 199 retval += hex2Int(c); 200 } 201 return true; 202 } else if (oct) { 203 for (i = 2; i <= last ; i++) { 204 c = value[i]; 205 if (!isOct(c)) 206 return false; 207 208 if (retval > octmax) return false; 209 retval *= 8; 210 retval += (c - '0'); 211 } 212 return true; 213 } 214 215 for (i = 2; i < last ; i++) { 216 c = value[i]; 217 if (!isDec(c)) 218 goto multiply; 219 220 if (retval > decmax) return false; 221 bool atmax = retval == decmax; 222 retval *= 10; 223 retval += c - '0'; 224 if (atmax && retval < decmax) return false; 225 if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 226 return false; 227 } 228 229 c = value[last]; 230 if (isDec(c)) { 231 232 if (retval > decmax) return false; 233 bool atmax = retval == decmax; 234 retval *= 10; 235 retval += c - '0'; 236 if (atmax && retval < decmax) return false; 237 if (sign && negative) { 238 if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 239 retval >= (T)-signmax) 240 return false; 241 retval = -retval; 242 } 243 else 244 if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 245 return false; 246 return true; 247 } 248 249 multiply: 250 signed long long mult = 1; 251 T val; 252 switch (c) { 253 case 'k': 254 case 'K': 255 if (i != last) return false; 256 mult = 1024; 257 val = signmax / mult; 258 break; 259 case 'm': 260 case 'M': 261 if (i != last) return false; 262 mult = 1024 * 1024; 263 val = signmax / mult; 264 break; 265 case 'g': 266 case 'G': 267 if (i != last) return false; 268 mult = 1024 * 1024 * 1024; 269 val = signmax / mult; 270 break; 271 case 'e': 272 case 'E': 273 if (i >= last) return false; 274 275 mult = 0; 276 for (i++; i <= last; i++) { 277 c = value[i]; 278 if (!isDec(c)) 279 return false; 280 281 mult *= 10; 282 mult += c - '0'; 283 } 284 285 for (i = 0; i < mult; i++) { 286 if (retval > signmax / 10) 287 return false; 288 retval *= 10; 289 if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 290 return false; 291 } 292 if (sign && negative) { 293 if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 294 retval >= (T)-signmax) 295 return false; 296 retval = -retval; 297 } 298 else 299 if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 300 return false; 301 302 return true; 303 304 default: 305 return false; 306 } 307 308 if (sign && negative) 309 return false; 310 311 if (mult > (unsigned long long)signmax) 312 return false; 313 314 if (retval > val) 315 return false; 316 317 retval *= mult; 318 319 return true; 320} 321 322#define STN(type) \ 323template<> \ 324bool to_number<type>(const string &value, type &retval) \ 325{ return __to_number(value, retval); } 326 327STN(unsigned long long) 328STN(signed long long) 329STN(unsigned long) 330STN(signed long) 331STN(unsigned int) 332STN(signed int) 333STN(unsigned short) 334STN(signed short) 335STN(unsigned char) 336STN(signed char) 337STN(char) 338 339template<> 340bool to_number<bool>(const string &value, bool &retval) 341{ 342 string lowered = to_lower(value); 343 344 if (value == "0") { 345 retval = false; 346 return true; 347 } 348 349 if (value == "1"){ 350 retval = true; 351 return true; 352 } 353 354 if (lowered == "false") { 355 retval = false; 356 return true; 357 } 358 359 if (lowered == "true"){ 360 retval = true; 361 return true; 362 } 363 364 if (lowered == "no") { 365 retval = false; 366 return true; 367 } 368 369 if (lowered == "yes"){ 370 retval = true; 371 return true; 372 } 373 374 return false; 375} | |