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; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 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.
| 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; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 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
|
27 */ 28 29#include <ctype.h> 30 31#include <cstring> 32#include <iostream> 33#include <string> 34#include <vector> 35 36#include "base/intmath.hh" 37#include "base/str.hh" 38 39using namespace std; 40 41bool 42split_first(const string &s, string &lhs, string &rhs, char c) 43{ 44 string::size_type offset = s.find(c); 45 if (offset == string::npos) { 46 lhs = s; 47 rhs = ""; 48 return false; 49 } 50 51 lhs = s.substr(0, offset); 52 rhs = s.substr(offset + 1); 53 return true; 54} 55 56bool 57split_last(const string &s, string &lhs, string &rhs, char c) 58{ 59 string::size_type offset = s.rfind(c); 60 if (offset == string::npos) { 61 lhs = s; 62 rhs = ""; 63 return false; 64 } 65 66 lhs = s.substr(0, offset); 67 rhs = s.substr(offset + 1); 68 return true; 69} 70 71void 72tokenize(vector<string>& v, const string &s, char token, bool ignore) 73{ 74 string::size_type first = 0; 75 string::size_type last = s.find_first_of(token); 76 77 if (s.empty()) 78 return; 79 80 if (ignore && last == first) { 81 while (last == first) 82 last = s.find_first_of(token, ++first); 83 84 if (last == string::npos) { 85 if (first != s.size()) 86 v.push_back(s.substr(first)); 87 return; 88 } 89 } 90 91 while (last != string::npos) { 92 v.push_back(s.substr(first, last - first)); 93 94 if (ignore) { 95 first = s.find_first_not_of(token, last + 1); 96 97 if (first == string::npos) 98 return; 99 } else 100 first = last + 1; 101 102 last = s.find_first_of(token, first); 103 } 104 105 v.push_back(s.substr(first)); 106} 107 108/** 109 * @todo This function will not handle the smallest negative decimal 110 * value for a signed type 111 */ 112 113template <class T> 114inline bool 115__to_number(string value, T &retval) 116{ 117 static const T maxnum = ((T)-1); 118 static const bool sign = maxnum < 0; 119 static const int bits = sizeof(T) * 8; 120 static const T hexmax = maxnum & (((T)1 << (bits - 4 - sign)) - 1); 121 static const T octmax = maxnum & (((T)1 << (bits - 3 - sign)) - 1); 122 static const T signmax = 123 (sign) ? maxnum & (((T)1 << (bits - 1)) - 1) : maxnum; 124 static const T decmax = signmax / 10; 125 126#if 0 127 cout << "maxnum = 0x" << hex << (unsigned long long)maxnum << "\n" 128 << "sign = 0x" << hex << (unsigned long long)sign << "\n" 129 << "hexmax = 0x" << hex << (unsigned long long)hexmax << "\n" 130 << "octmax = 0x" << hex << (unsigned long long)octmax << "\n" 131 << "signmax = 0x" << hex << (unsigned long long)signmax << "\n" 132 << "decmax = 0x" << hex << (unsigned long long)decmax << "\n"; 133#endif 134 135 eat_white(value); 136 137 bool negative = false; 138 bool hex = false; 139 bool oct = false; 140 int last = value.size() - 1; 141 retval = 0; 142 int i = 0; 143 144 char c = value[i]; 145 if (!isDec(c)) { 146 if (c == '-' && sign) 147 negative = true; 148 else 149 return false; 150 } 151 else { 152 retval += c - '0'; 153 if (last == 0) return true; 154 } 155 156 if (c == '0') 157 oct = true; 158 159 c = value[++i]; 160 if (oct) { 161 if (sign && negative) 162 return false; 163 164 if (!isOct(c)) { 165 if (c == 'X' || c == 'x') { 166 hex = true; 167 oct = false; 168 } else 169 return false; 170 } 171 else 172 retval += c - '0'; 173 } else if (!isDec(c)) 174 goto multiply; 175 else { 176 if (sign && negative && c == '0') 177 return false; 178 179 retval *= 10; 180 retval += c - '0'; 181 if (last == 1) { 182 if (sign && negative) retval = -retval; 183 return true; 184 } 185 } 186 187 if (hex) { 188 if (last == 1) 189 return false; 190 191 for (i = 2; i <= last ; i++) { 192 c = value[i]; 193 if (!isHex(c)) 194 return false; 195 196 if (retval > hexmax) return false; 197 retval *= 16; 198 retval += hex2Int(c); 199 } 200 return true; 201 } else if (oct) { 202 for (i = 2; i <= last ; i++) { 203 c = value[i]; 204 if (!isOct(c)) 205 return false; 206 207 if (retval > octmax) return false; 208 retval *= 8; 209 retval += (c - '0'); 210 } 211 return true; 212 } 213 214 for (i = 2; i < last ; i++) { 215 c = value[i]; 216 if (!isDec(c)) 217 goto multiply; 218 219 if (retval > decmax) return false; 220 bool atmax = retval == decmax; 221 retval *= 10; 222 retval += c - '0'; 223 if (atmax && retval < decmax) return false; 224 if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 225 return false; 226 } 227 228 c = value[last]; 229 if (isDec(c)) { 230 231 if (retval > decmax) return false; 232 bool atmax = retval == decmax; 233 retval *= 10; 234 retval += c - '0'; 235 if (atmax && retval < decmax) return false; 236 if (sign && negative) { 237 if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 238 retval >= (T)-signmax) 239 return false; 240 retval = -retval; 241 } 242 else 243 if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 244 return false; 245 return true; 246 } 247 248 multiply: 249 signed long long mult = 1; 250 T val; 251 switch (c) { 252 case 'k': 253 case 'K': 254 if (i != last) return false; 255 mult = 1024; 256 val = signmax / mult; 257 break; 258 case 'm': 259 case 'M': 260 if (i != last) return false; 261 mult = 1024 * 1024; 262 val = signmax / mult; 263 break; 264 case 'g': 265 case 'G': 266 if (i != last) return false; 267 mult = 1024 * 1024 * 1024; 268 val = signmax / mult; 269 break; 270 case 'e': 271 case 'E': 272 if (i >= last) return false; 273 274 mult = 0; 275 for (i++; i <= last; i++) { 276 c = value[i]; 277 if (!isDec(c)) 278 return false; 279 280 mult *= 10; 281 mult += c - '0'; 282 } 283 284 for (i = 0; i < mult; i++) { 285 if (retval > signmax / 10) 286 return false; 287 retval *= 10; 288 if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 289 return false; 290 } 291 if (sign && negative) { 292 if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 293 retval >= (T)-signmax) 294 return false; 295 retval = -retval; 296 } 297 else 298 if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 299 return false; 300 301 return true; 302 303 default: 304 return false; 305 } 306 307 if (sign && negative) 308 return false; 309 310 if (mult > (unsigned long long)signmax) 311 return false; 312 313 if (retval > val) 314 return false; 315 316 retval *= mult; 317 318 return true; 319} 320 321#define STN(type) \ 322template<> \ 323bool to_number<type>(const string &value, type &retval) \ 324{ return __to_number(value, retval); } 325 326STN(unsigned long long); 327STN(signed long long); 328STN(unsigned long); 329STN(signed long); 330STN(unsigned int); 331STN(signed int); 332STN(unsigned short); 333STN(signed short); 334STN(unsigned char); 335STN(signed char); 336 337template<> 338bool to_number<bool>(const string &value, bool &retval) 339{ 340 string lowered = to_lower(value); 341 342 if (value == "0") { 343 retval = false; 344 return true; 345 } 346 347 if (value == "1"){ 348 retval = true; 349 return true; 350 } 351 352 if (lowered == "false") { 353 retval = false; 354 return true; 355 } 356 357 if (lowered == "true"){ 358 retval = true; 359 return true; 360 } 361 362 if (lowered == "no") { 363 retval = false; 364 return true; 365 } 366 367 if (lowered == "yes"){ 368 retval = true; 369 return true; 370 } 371 372 return false; 373}
| 29 */ 30 31#include <ctype.h> 32 33#include <cstring> 34#include <iostream> 35#include <string> 36#include <vector> 37 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); 47 if (offset == string::npos) { 48 lhs = s; 49 rhs = ""; 50 return false; 51 } 52 53 lhs = s.substr(0, offset); 54 rhs = s.substr(offset + 1); 55 return true; 56} 57 58bool 59split_last(const string &s, string &lhs, string &rhs, char c) 60{ 61 string::size_type offset = s.rfind(c); 62 if (offset == string::npos) { 63 lhs = s; 64 rhs = ""; 65 return false; 66 } 67 68 lhs = s.substr(0, offset); 69 rhs = s.substr(offset + 1); 70 return true; 71} 72 73void 74tokenize(vector<string>& v, const string &s, char token, bool ignore) 75{ 76 string::size_type first = 0; 77 string::size_type last = s.find_first_of(token); 78 79 if (s.empty()) 80 return; 81 82 if (ignore && last == first) { 83 while (last == first) 84 last = s.find_first_of(token, ++first); 85 86 if (last == string::npos) { 87 if (first != s.size()) 88 v.push_back(s.substr(first)); 89 return; 90 } 91 } 92 93 while (last != string::npos) { 94 v.push_back(s.substr(first, last - first)); 95 96 if (ignore) { 97 first = s.find_first_not_of(token, last + 1); 98 99 if (first == string::npos) 100 return; 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} 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 = maxnum < 0; 121 static const int bits = sizeof(T) * 8; 122 static const T hexmax = maxnum & (((T)1 << (bits - 4 - sign)) - 1); 123 static const T octmax = maxnum & (((T)1 << (bits - 3 - sign)) - 1); 124 static const T signmax = 125 (sign) ? maxnum & (((T)1 << (bits - 1)) - 1) : maxnum; 126 static const T decmax = signmax / 10; 127 128#if 0 129 cout << "maxnum = 0x" << hex << (unsigned long long)maxnum << "\n" 130 << "sign = 0x" << hex << (unsigned long long)sign << "\n" 131 << "hexmax = 0x" << hex << (unsigned long long)hexmax << "\n" 132 << "octmax = 0x" << hex << (unsigned long long)octmax << "\n" 133 << "signmax = 0x" << hex << (unsigned long long)signmax << "\n" 134 << "decmax = 0x" << hex << (unsigned long long)decmax << "\n"; 135#endif 136 137 eat_white(value); 138 139 bool negative = false; 140 bool hex = false; 141 bool oct = false; 142 int last = value.size() - 1; 143 retval = 0; 144 int i = 0; 145 146 char c = value[i]; 147 if (!isDec(c)) { 148 if (c == '-' && sign) 149 negative = true; 150 else 151 return false; 152 } 153 else { 154 retval += c - '0'; 155 if (last == 0) return true; 156 } 157 158 if (c == '0') 159 oct = true; 160 161 c = value[++i]; 162 if (oct) { 163 if (sign && negative) 164 return false; 165 166 if (!isOct(c)) { 167 if (c == 'X' || c == 'x') { 168 hex = true; 169 oct = false; 170 } else 171 return false; 172 } 173 else 174 retval += c - '0'; 175 } else if (!isDec(c)) 176 goto multiply; 177 else { 178 if (sign && negative && c == '0') 179 return false; 180 181 retval *= 10; 182 retval += c - '0'; 183 if (last == 1) { 184 if (sign && negative) retval = -retval; 185 return true; 186 } 187 } 188 189 if (hex) { 190 if (last == 1) 191 return false; 192 193 for (i = 2; i <= last ; i++) { 194 c = value[i]; 195 if (!isHex(c)) 196 return false; 197 198 if (retval > hexmax) return false; 199 retval *= 16; 200 retval += hex2Int(c); 201 } 202 return true; 203 } else if (oct) { 204 for (i = 2; i <= last ; i++) { 205 c = value[i]; 206 if (!isOct(c)) 207 return false; 208 209 if (retval > octmax) return false; 210 retval *= 8; 211 retval += (c - '0'); 212 } 213 return true; 214 } 215 216 for (i = 2; i < last ; i++) { 217 c = value[i]; 218 if (!isDec(c)) 219 goto multiply; 220 221 if (retval > decmax) return false; 222 bool atmax = retval == decmax; 223 retval *= 10; 224 retval += c - '0'; 225 if (atmax && retval < decmax) return false; 226 if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 227 return false; 228 } 229 230 c = value[last]; 231 if (isDec(c)) { 232 233 if (retval > decmax) return false; 234 bool atmax = retval == decmax; 235 retval *= 10; 236 retval += c - '0'; 237 if (atmax && retval < decmax) return false; 238 if (sign && negative) { 239 if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 240 retval >= (T)-signmax) 241 return false; 242 retval = -retval; 243 } 244 else 245 if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 246 return false; 247 return true; 248 } 249 250 multiply: 251 signed long long mult = 1; 252 T val; 253 switch (c) { 254 case 'k': 255 case 'K': 256 if (i != last) return false; 257 mult = 1024; 258 val = signmax / mult; 259 break; 260 case 'm': 261 case 'M': 262 if (i != last) return false; 263 mult = 1024 * 1024; 264 val = signmax / mult; 265 break; 266 case 'g': 267 case 'G': 268 if (i != last) return false; 269 mult = 1024 * 1024 * 1024; 270 val = signmax / mult; 271 break; 272 case 'e': 273 case 'E': 274 if (i >= last) return false; 275 276 mult = 0; 277 for (i++; i <= last; i++) { 278 c = value[i]; 279 if (!isDec(c)) 280 return false; 281 282 mult *= 10; 283 mult += c - '0'; 284 } 285 286 for (i = 0; i < mult; i++) { 287 if (retval > signmax / 10) 288 return false; 289 retval *= 10; 290 if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 291 return false; 292 } 293 if (sign && negative) { 294 if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 295 retval >= (T)-signmax) 296 return false; 297 retval = -retval; 298 } 299 else 300 if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 301 return false; 302 303 return true; 304 305 default: 306 return false; 307 } 308 309 if (sign && negative) 310 return false; 311 312 if (mult > (unsigned long long)signmax) 313 return false; 314 315 if (retval > val) 316 return false; 317 318 retval *= mult; 319 320 return true; 321} 322 323#define STN(type) \ 324template<> \ 325bool to_number<type>(const string &value, type &retval) \ 326{ return __to_number(value, retval); } 327 328STN(unsigned long long); 329STN(signed long long); 330STN(unsigned long); 331STN(signed long); 332STN(unsigned int); 333STN(signed int); 334STN(unsigned short); 335STN(signed short); 336STN(unsigned char); 337STN(signed 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}
|