str.cc revision 1793
18706Sandreas.hansson@arm.com/* 28706Sandreas.hansson@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 38706Sandreas.hansson@arm.com * All rights reserved. 48706Sandreas.hansson@arm.com * 58706Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68706Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78706Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88706Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98706Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108706Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118706Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128706Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 136892SBrad.Beckmann@amd.com * contributors may be used to endorse or promote products derived from 146892SBrad.Beckmann@amd.com * this software without specific prior written permission. 156892SBrad.Beckmann@amd.com * 166892SBrad.Beckmann@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176892SBrad.Beckmann@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186892SBrad.Beckmann@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196892SBrad.Beckmann@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206892SBrad.Beckmann@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216892SBrad.Beckmann@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226892SBrad.Beckmann@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236892SBrad.Beckmann@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246892SBrad.Beckmann@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256892SBrad.Beckmann@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266892SBrad.Beckmann@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276892SBrad.Beckmann@amd.com */ 286892SBrad.Beckmann@amd.com 296892SBrad.Beckmann@amd.com#include <ctype.h> 306892SBrad.Beckmann@amd.com 316892SBrad.Beckmann@amd.com#include <cstring> 326892SBrad.Beckmann@amd.com#include <iostream> 336892SBrad.Beckmann@amd.com#include <string> 346892SBrad.Beckmann@amd.com#include <vector> 356892SBrad.Beckmann@amd.com 366892SBrad.Beckmann@amd.com#include "base/intmath.hh" 376892SBrad.Beckmann@amd.com#include "base/str.hh" 386892SBrad.Beckmann@amd.com 396892SBrad.Beckmann@amd.comusing namespace std; 406892SBrad.Beckmann@amd.com 416892SBrad.Beckmann@amd.combool 427563SBrad.Beckmann@amd.comsplit_first(const string &s, string &lhs, string &rhs, char c) 436892SBrad.Beckmann@amd.com{ 446892SBrad.Beckmann@amd.com string::size_type offset = s.find(c); 456892SBrad.Beckmann@amd.com if (offset == string::npos) { 466892SBrad.Beckmann@amd.com lhs = s; 477538SBrad.Beckmann@amd.com rhs = ""; 488939SBrad.Beckmann@amd.com return false; 498939SBrad.Beckmann@amd.com } 508939SBrad.Beckmann@amd.com 519791Sakash.bagdia@arm.com lhs = s.substr(0, offset); 529791Sakash.bagdia@arm.com rhs = s.substr(offset + 1); 539791Sakash.bagdia@arm.com return true; 549791Sakash.bagdia@arm.com} 559841Snilay@cs.wisc.edu 569841Snilay@cs.wisc.edubool 579841Snilay@cs.wisc.edusplit_last(const string &s, string &lhs, string &rhs, char c) 589841Snilay@cs.wisc.edu{ 599841Snilay@cs.wisc.edu string::size_type offset = s.rfind(c); 607538SBrad.Beckmann@amd.com if (offset == string::npos) { 617538SBrad.Beckmann@amd.com lhs = s; 627538SBrad.Beckmann@amd.com rhs = ""; 637538SBrad.Beckmann@amd.com return false; 647538SBrad.Beckmann@amd.com } 659576Snilay@cs.wisc.edu 669576Snilay@cs.wisc.edu lhs = s.substr(0, offset); 678612Stushar@csail.mit.edu rhs = s.substr(offset + 1); 688612Stushar@csail.mit.edu return true; 697538SBrad.Beckmann@amd.com} 707538SBrad.Beckmann@amd.com 717917SBrad.Beckmann@amd.comvoid 727563SBrad.Beckmann@amd.comtokenize(vector<string>& v, const string &s, char token, bool ignore) 737563SBrad.Beckmann@amd.com{ 747538SBrad.Beckmann@amd.com string::size_type first = 0; 757538SBrad.Beckmann@amd.com string::size_type last = s.find_first_of(token); 767538SBrad.Beckmann@amd.com 777538SBrad.Beckmann@amd.com if (s.empty()) 787538SBrad.Beckmann@amd.com return; 797566SBrad.Beckmann@amd.com 807566SBrad.Beckmann@amd.com if (ignore && last == first) { 817809Snilay@cs.wisc.edu while (last == first) 827809Snilay@cs.wisc.edu last = s.find_first_of(token, ++first); 837809Snilay@cs.wisc.edu 847809Snilay@cs.wisc.edu if (last == string::npos) { 858638Sgloh if (first != s.size()) 868638Sgloh v.push_back(s.substr(first)); 877538SBrad.Beckmann@amd.com return; 887538SBrad.Beckmann@amd.com } 897538SBrad.Beckmann@amd.com } 907538SBrad.Beckmann@amd.com 919100SBrad.Beckmann@amd.com while (last != string::npos) { 929100SBrad.Beckmann@amd.com v.push_back(s.substr(first, last - first)); 939100SBrad.Beckmann@amd.com 949100SBrad.Beckmann@amd.com if (ignore) { 959100SBrad.Beckmann@amd.com first = s.find_first_not_of(token, last + 1); 969100SBrad.Beckmann@amd.com 979100SBrad.Beckmann@amd.com if (first == string::npos) 989100SBrad.Beckmann@amd.com return; 999100SBrad.Beckmann@amd.com } else 1009100SBrad.Beckmann@amd.com first = last + 1; 1018929Snilay@cs.wisc.edu 1026892SBrad.Beckmann@amd.com last = s.find_first_of(token, first); 10310012Snilay@cs.wisc.edu } 1048436SBrad.Beckmann@amd.com 1058436SBrad.Beckmann@amd.com v.push_back(s.substr(first)); 1067032SBrad.Beckmann@amd.com} 1077032SBrad.Beckmann@amd.com 1086923SBrad.Beckmann@amd.com/** 1099100SBrad.Beckmann@amd.com * @todo This function will not handle the smallest negative decimal 11010116Snilay@cs.wisc.edu * value for a signed type 1117557SBrad.Beckmann@amd.com */ 1126923SBrad.Beckmann@amd.com 1136923SBrad.Beckmann@amd.comtemplate <class T> 1147557SBrad.Beckmann@amd.cominline bool 1158257SBrad.Beckmann@amd.com__to_number(string value, T &retval) 1168706Sandreas.hansson@arm.com{ 1178706Sandreas.hansson@arm.com static const T maxnum = ((T)-1); 1188706Sandreas.hansson@arm.com static const bool sign = maxnum < 0; 1198923Sandreas.hansson@arm.com static const int bits = sizeof(T) * 8; 1208706Sandreas.hansson@arm.com static const T hexmax = maxnum & (((T)1 << (bits - 4 - sign)) - 1); 1218706Sandreas.hansson@arm.com static const T octmax = maxnum & (((T)1 << (bits - 3 - sign)) - 1); 1228706Sandreas.hansson@arm.com static const T signmax = 1238706Sandreas.hansson@arm.com (sign) ? maxnum & (((T)1 << (bits - 1)) - 1) : maxnum; 1248732Sandreas.hansson@arm.com static const T decmax = signmax / 10; 1258839Sandreas.hansson@arm.com 1268732Sandreas.hansson@arm.com#if 0 1278732Sandreas.hansson@arm.com cout << "maxnum = 0x" << hex << (unsigned long long)maxnum << "\n" 1288257SBrad.Beckmann@amd.com << "sign = 0x" << hex << (unsigned long long)sign << "\n" 1298257SBrad.Beckmann@amd.com << "hexmax = 0x" << hex << (unsigned long long)hexmax << "\n" 1308257SBrad.Beckmann@amd.com << "octmax = 0x" << hex << (unsigned long long)octmax << "\n" 1318257SBrad.Beckmann@amd.com << "signmax = 0x" << hex << (unsigned long long)signmax << "\n" 1328257SBrad.Beckmann@amd.com << "decmax = 0x" << hex << (unsigned long long)decmax << "\n"; 1338257SBrad.Beckmann@amd.com#endif 1348257SBrad.Beckmann@amd.com 1358257SBrad.Beckmann@amd.com eat_white(value); 1368257SBrad.Beckmann@amd.com 1378257SBrad.Beckmann@amd.com bool negative = false; 1388257SBrad.Beckmann@amd.com bool hex = false; 1398257SBrad.Beckmann@amd.com bool oct = false; 1408257SBrad.Beckmann@amd.com int last = value.size() - 1; 1418257SBrad.Beckmann@amd.com retval = 0; 1428257SBrad.Beckmann@amd.com int i = 0; 1438258SBrad.Beckmann@amd.com 1448258SBrad.Beckmann@amd.com char c = value[i]; 1459274Snilay@cs.wisc.edu if (!IsDec(c)) { 1469148Spowerjg@cs.wisc.edu if (c == '-' && sign) 1479148Spowerjg@cs.wisc.edu negative = true; 1489862Snilay@cs.wisc.edu else 1499862Snilay@cs.wisc.edu return false; 1509862Snilay@cs.wisc.edu } 1519862Snilay@cs.wisc.edu else { 1529862Snilay@cs.wisc.edu retval += c - '0'; 1538257SBrad.Beckmann@amd.com if (last == 0) return true; 1548612Stushar@csail.mit.edu } 1558612Stushar@csail.mit.edu 1569593Snilay@cs.wisc.edu if (c == '0') 1579593Snilay@cs.wisc.edu oct = true; 1586892SBrad.Beckmann@amd.com 1596903SBrad.Beckmann@amd.com c = value[++i]; 1607563SBrad.Beckmann@amd.com if (oct) { 1617025SBrad.Beckmann@amd.com if (sign && negative) 1629148Spowerjg@cs.wisc.edu return false; 1637025SBrad.Beckmann@amd.com 1647025SBrad.Beckmann@amd.com if (!IsOct(c)) { 1657563SBrad.Beckmann@amd.com if (c == 'X' || c == 'x') { 1666903SBrad.Beckmann@amd.com hex = true; 1676903SBrad.Beckmann@amd.com oct = false; 1687563SBrad.Beckmann@amd.com } else 1699318Spower.jg@gmail.com return false; 1709318Spower.jg@gmail.com } 1717563SBrad.Beckmann@amd.com else 1727563SBrad.Beckmann@amd.com retval += c - '0'; 1737563SBrad.Beckmann@amd.com } else if (!IsDec(c)) 1747563SBrad.Beckmann@amd.com goto multiply; 1759318Spower.jg@gmail.com else { 1769318Spower.jg@gmail.com if (sign && negative && c == '0') 1779318Spower.jg@gmail.com return false; 17810004Snilay@cs.wisc.edu 1799318Spower.jg@gmail.com retval *= 10; 1809148Spowerjg@cs.wisc.edu retval += c - '0'; 1816903SBrad.Beckmann@amd.com if (last == 1) { 1826903SBrad.Beckmann@amd.com if (sign && negative) retval = -retval; 1837563SBrad.Beckmann@amd.com return true; 1849148Spowerjg@cs.wisc.edu } 1859826Sandreas.hansson@arm.com } 1868931Sandreas.hansson@arm.com 1876892SBrad.Beckmann@amd.com if (hex) { 1888436SBrad.Beckmann@amd.com if (last == 1) 1898436SBrad.Beckmann@amd.com return false; 19010116Snilay@cs.wisc.edu 19110116Snilay@cs.wisc.edu for (i = 2; i <= last ; i++) { 19210116Snilay@cs.wisc.edu c = value[i]; 19310116Snilay@cs.wisc.edu if (!IsHex(c)) 19410116Snilay@cs.wisc.edu return false; 19510116Snilay@cs.wisc.edu 19610116Snilay@cs.wisc.edu if (retval > hexmax) return false; 19710116Snilay@cs.wisc.edu retval *= 16; 19810116Snilay@cs.wisc.edu retval += Hex2Int(c); 19910116Snilay@cs.wisc.edu } 2008322Ssteve.reinhardt@amd.com return true; 20110012Snilay@cs.wisc.edu } else if (oct) { 2027809Snilay@cs.wisc.edu 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} 374