str.cc revision 2020
11689SN/A/* 210032SGiacomo.Gabrielli@arm.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 39920Syasuko.eckert@amd.com * All rights reserved. 47944SGiacomo.Gabrielli@arm.com * 57944SGiacomo.Gabrielli@arm.com * Redistribution and use in source and binary forms, with or without 67944SGiacomo.Gabrielli@arm.com * modification, are permitted provided that the following conditions are 77944SGiacomo.Gabrielli@arm.com * met: redistributions of source code must retain the above copyright 87944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer; 97944SGiacomo.Gabrielli@arm.com * redistributions in binary form must reproduce the above copyright 107944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the 117944SGiacomo.Gabrielli@arm.com * documentation and/or other materials provided with the distribution; 127944SGiacomo.Gabrielli@arm.com * neither the name of the copyright holders nor the names of its 137944SGiacomo.Gabrielli@arm.com * contributors may be used to endorse or promote products derived from 147944SGiacomo.Gabrielli@arm.com * this software without specific prior written permission. 152326SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271689SN/A */ 281689SN/A 291689SN/A#include <ctype.h> 301689SN/A 311689SN/A#include <cstring> 321689SN/A#include <iostream> 331689SN/A#include <string> 341689SN/A#include <vector> 351689SN/A 361689SN/A#include "base/intmath.hh" 371689SN/A#include "base/str.hh" 381689SN/A 391689SN/Ausing namespace std; 402665Ssaidi@eecs.umich.edu 412665Ssaidi@eecs.umich.edubool 422831Sksewell@umich.edusplit_first(const string &s, string &lhs, string &rhs, char c) 431689SN/A{ 441689SN/A string::size_type offset = s.find(c); 459944Smatt.horsnell@ARM.com if (offset == string::npos) { 469944Smatt.horsnell@ARM.com lhs = s; 479944Smatt.horsnell@ARM.com rhs = ""; 482064SN/A return false; 491060SN/A } 501060SN/A 512292SN/A lhs = s.substr(0, offset); 521717SN/A rhs = s.substr(offset + 1); 538232Snate@binkert.org return true; 544762Snate@binkert.org} 556221Snate@binkert.org 564762Snate@binkert.orgbool 571060SN/Asplit_last(const string &s, string &lhs, string &rhs, char c) 588737Skoansin.tan@gmail.com{ 598737Skoansin.tan@gmail.com string::size_type offset = s.rfind(c); 608737Skoansin.tan@gmail.com if (offset == string::npos) { 615529Snate@binkert.org lhs = s; 621061SN/A rhs = ""; 632292SN/A return false; 645606Snate@binkert.org } 658581Ssteve.reinhardt@amd.com 668581Ssteve.reinhardt@amd.com lhs = s.substr(0, offset); 671060SN/A rhs = s.substr(offset + 1); 682292SN/A return true; 692292SN/A} 702292SN/A 712292SN/Avoid 722292SN/Atokenize(vector<string>& v, const string &s, char token, bool ignore) 732292SN/A{ 742326SN/A string::size_type first = 0; 752292SN/A string::size_type last = s.find_first_of(token); 762292SN/A 772292SN/A if (s.empty()) 782292SN/A return; 792292SN/A 802292SN/A if (ignore && last == first) { 815336Shines@cs.fsu.edu while (last == first) 822292SN/A last = s.find_first_of(token, ++first); 834873Sstever@eecs.umich.edu 842292SN/A if (last == string::npos) { 852292SN/A if (first != s.size()) 862292SN/A v.push_back(s.substr(first)); 874329Sktlim@umich.edu return; 885529Snate@binkert.org } 894329Sktlim@umich.edu } 904329Sktlim@umich.edu 914329Sktlim@umich.edu while (last != string::npos) { 922292SN/A v.push_back(s.substr(first, last - first)); 932292SN/A 942292SN/A if (ignore) { 952292SN/A first = s.find_first_not_of(token, last + 1); 962292SN/A 972292SN/A if (first == string::npos) 985529Snate@binkert.org return; 991060SN/A } else 1009920Syasuko.eckert@amd.com first = last + 1; 1019920Syasuko.eckert@amd.com 1029920Syasuko.eckert@amd.com last = s.find_first_of(token, first); 1031060SN/A } 1041060SN/A 1051060SN/A v.push_back(s.substr(first)); 1062326SN/A} 1071060SN/A 1081060SN/A/** 1091060SN/A * @todo This function will not handle the smallest negative decimal 1101060SN/A * value for a signed type 1112292SN/A */ 1126221Snate@binkert.org 1136221Snate@binkert.orgtemplate <class T> 1146221Snate@binkert.orginline bool 1151060SN/A__to_number(string value, T &retval) 1161060SN/A{ 1172307SN/A static const T maxnum = ((T)-1); 1182292SN/A static const bool sign = maxnum < 0; 1192980Sgblack@eecs.umich.edu static const int bits = sizeof(T) * 8; 1202292SN/A static const T hexmax = maxnum & (((T)1 << (bits - 4 - sign)) - 1); 1212292SN/A static const T octmax = maxnum & (((T)1 << (bits - 3 - sign)) - 1); 1222292SN/A static const T signmax = 1232292SN/A (sign) ? maxnum & (((T)1 << (bits - 1)) - 1) : maxnum; 1242292SN/A static const T decmax = signmax / 10; 1252292SN/A 1262292SN/A#if 0 1272292SN/A cout << "maxnum = 0x" << hex << (unsigned long long)maxnum << "\n" 1282292SN/A << "sign = 0x" << hex << (unsigned long long)sign << "\n" 1292292SN/A << "hexmax = 0x" << hex << (unsigned long long)hexmax << "\n" 1306221Snate@binkert.org << "octmax = 0x" << hex << (unsigned long long)octmax << "\n" 1316221Snate@binkert.org << "signmax = 0x" << hex << (unsigned long long)signmax << "\n" 1322292SN/A << "decmax = 0x" << hex << (unsigned long long)decmax << "\n"; 1332292SN/A#endif 1342292SN/A 1352292SN/A eat_white(value); 1362292SN/A 1372292SN/A bool negative = false; 1382292SN/A bool hex = false; 1392292SN/A bool oct = false; 1402292SN/A int last = value.size() - 1; 1416221Snate@binkert.org retval = 0; 1426221Snate@binkert.org int i = 0; 1432292SN/A 1442292SN/A char c = value[i]; 1452831Sksewell@umich.edu if (!isDec(c)) { 1462292SN/A if (c == '-' && sign) 1472292SN/A negative = true; 1482292SN/A else 1492292SN/A return false; 1502292SN/A } 1512292SN/A else { 1522292SN/A retval += c - '0'; 1532292SN/A if (last == 0) return true; 1542292SN/A } 1556221Snate@binkert.org 1566221Snate@binkert.org if (c == '0') 1572292SN/A oct = true; 1582292SN/A 1592831Sksewell@umich.edu c = value[++i]; 1602292SN/A if (oct) { 1612292SN/A if (sign && negative) 1622292SN/A return false; 1632292SN/A 1642292SN/A if (!isOct(c)) { 1652292SN/A if (c == 'X' || c == 'x') { 1662292SN/A hex = true; 1672292SN/A oct = false; 1682292SN/A } else 1692292SN/A return false; 1702326SN/A } 1712348SN/A else 1722326SN/A retval += c - '0'; 1732326SN/A } else if (!isDec(c)) 1742348SN/A goto multiply; 1752292SN/A else { 1762292SN/A if (sign && negative && c == '0') 1772292SN/A return false; 1782292SN/A 1792292SN/A retval *= 10; 1802292SN/A retval += c - '0'; 1812292SN/A if (last == 1) { 1821060SN/A if (sign && negative) retval = -retval; 1831060SN/A return true; 1841061SN/A } 1851060SN/A } 1861062SN/A 1871062SN/A if (hex) { 1882301SN/A if (last == 1) 1891062SN/A return false; 1901062SN/A 1911062SN/A for (i = 2; i <= last ; i++) { 1921062SN/A c = value[i]; 1931062SN/A if (!isHex(c)) 1941062SN/A return false; 1951062SN/A 1961062SN/A if (retval > hexmax) return false; 1971062SN/A retval *= 16; 1981062SN/A retval += hex2Int(c); 1992301SN/A } 2002301SN/A return true; 2012301SN/A } else if (oct) { 2022301SN/A for (i = 2; i <= last ; i++) { 2031062SN/A c = value[i]; 2041062SN/A if (!isOct(c)) 2051062SN/A return false; 2061062SN/A 2071062SN/A if (retval > octmax) return false; 2081062SN/A retval *= 8; 2091062SN/A retval += (c - '0'); 2101062SN/A } 2111062SN/A return true; 2121062SN/A } 2131062SN/A 2141062SN/A for (i = 2; i < last ; i++) { 2151062SN/A c = value[i]; 2161062SN/A if (!isDec(c)) 2171062SN/A goto multiply; 2181062SN/A 2191062SN/A if (retval > decmax) return false; 2201062SN/A bool atmax = retval == decmax; 2211062SN/A retval *= 10; 2221062SN/A retval += c - '0'; 2231062SN/A if (atmax && retval < decmax) return false; 2241062SN/A if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 2251062SN/A return false; 2261062SN/A } 2271062SN/A 2281062SN/A c = value[last]; 2291062SN/A if (isDec(c)) { 2301062SN/A 2311062SN/A if (retval > decmax) return false; 2321062SN/A bool atmax = retval == decmax; 2331062SN/A retval *= 10; 2341062SN/A retval += c - '0'; 2351062SN/A if (atmax && retval < decmax) return false; 2361062SN/A if (sign && negative) { 2371062SN/A if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 2381062SN/A retval >= (T)-signmax) 2391062SN/A return false; 2401062SN/A retval = -retval; 2411062SN/A } 2421062SN/A else 2431062SN/A if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 2441062SN/A return false; 2451062SN/A return true; 2461062SN/A } 2471062SN/A 2481062SN/A multiply: 2491062SN/A signed long long mult = 1; 2502361SN/A T val; 2512326SN/A switch (c) { 2522301SN/A case 'k': 2532301SN/A case 'K': 2542301SN/A if (i != last) return false; 2552301SN/A mult = 1024; 2562301SN/A val = signmax / mult; 2572301SN/A break; 2582326SN/A case 'm': 2592301SN/A case 'M': 2602361SN/A if (i != last) return false; 2612326SN/A mult = 1024 * 1024; 2622307SN/A val = signmax / mult; 2638240Snate@binkert.org break; 2642301SN/A case 'g': 2652307SN/A case 'G': 2662301SN/A if (i != last) return false; 2672301SN/A mult = 1024 * 1024 * 1024; 2682301SN/A val = signmax / mult; 2692301SN/A break; 2708240Snate@binkert.org case 'e': 2712301SN/A case 'E': 2722301SN/A if (i >= last) return false; 2732301SN/A 2742301SN/A mult = 0; 2752301SN/A for (i++; i <= last; i++) { 2762301SN/A c = value[i]; 2772301SN/A if (!isDec(c)) 2782326SN/A return false; 2794762Snate@binkert.org 2808240Snate@binkert.org mult *= 10; 2812301SN/A mult += c - '0'; 2822301SN/A } 2832301SN/A 2844762Snate@binkert.org for (i = 0; i < mult; i++) { 2852301SN/A if (retval > signmax / 10) 2862301SN/A return false; 2872301SN/A retval *= 10; 2882301SN/A if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 2892361SN/A return false; 2902326SN/A } 2912301SN/A if (sign && negative) { 2928240Snate@binkert.org if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 2932301SN/A retval >= (T)-signmax) 2942301SN/A return false; 2952301SN/A retval = -retval; 2962301SN/A } 2972301SN/A else 2982980Sgblack@eecs.umich.edu if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 2992301SN/A return false; 3002326SN/A 3012301SN/A return true; 3022361SN/A 3032326SN/A default: 3048240Snate@binkert.org return false; 3052301SN/A } 3062301SN/A 3072301SN/A if (sign && negative) 3082326SN/A return false; 3092727Sktlim@umich.edu 3102326SN/A if (mult > (unsigned long long)signmax) 3112301SN/A return false; 3128240Snate@binkert.org 3132301SN/A if (retval > val) 3142301SN/A return false; 3152301SN/A 3162301SN/A retval *= mult; 3174762Snate@binkert.org 3182301SN/A return true; 3192301SN/A} 3202326SN/A 3212301SN/A#define STN(type) \ 3228240Snate@binkert.orgtemplate<> \ 3232301SN/Abool to_number<type>(const string &value, type &retval) \ 3242301SN/A{ return __to_number(value, retval); } 3252301SN/A 3262301SN/ASTN(unsigned long long); 3272326SN/ASTN(signed long long); 3288240Snate@binkert.orgSTN(unsigned long); 3292301SN/ASTN(signed long); 3302301SN/ASTN(unsigned int); 3312301SN/ASTN(signed int); 3322326SN/ASTN(unsigned short); 3332301SN/ASTN(signed short); 3346221Snate@binkert.orgSTN(unsigned char); 3352292SN/ASTN(signed char); 3366221Snate@binkert.org 3372292SN/Atemplate<> 3387897Shestness@cs.utexas.edubool to_number<bool>(const string &value, bool &retval) 3397897Shestness@cs.utexas.edu{ 3407897Shestness@cs.utexas.edu string lowered = to_lower(value); 3417897Shestness@cs.utexas.edu 3427897Shestness@cs.utexas.edu if (value == "0") { 3437897Shestness@cs.utexas.edu retval = false; 3447897Shestness@cs.utexas.edu return true; 3457897Shestness@cs.utexas.edu } 3467897Shestness@cs.utexas.edu 3477897Shestness@cs.utexas.edu if (value == "1"){ 3487897Shestness@cs.utexas.edu retval = true; 3497897Shestness@cs.utexas.edu return true; 3507897Shestness@cs.utexas.edu } 3517897Shestness@cs.utexas.edu 3527897Shestness@cs.utexas.edu if (lowered == "false") { 3537897Shestness@cs.utexas.edu retval = false; 3547897Shestness@cs.utexas.edu return true; 3557897Shestness@cs.utexas.edu } 3567897Shestness@cs.utexas.edu 3577897Shestness@cs.utexas.edu if (lowered == "true"){ 3587897Shestness@cs.utexas.edu retval = true; 3597897Shestness@cs.utexas.edu return true; 3607897Shestness@cs.utexas.edu } 3617897Shestness@cs.utexas.edu 3627897Shestness@cs.utexas.edu if (lowered == "no") { 3637897Shestness@cs.utexas.edu retval = false; 3647897Shestness@cs.utexas.edu return true; 3657897Shestness@cs.utexas.edu } 3667897Shestness@cs.utexas.edu 3677897Shestness@cs.utexas.edu if (lowered == "yes"){ 3687897Shestness@cs.utexas.edu retval = true; 3697897Shestness@cs.utexas.edu return true; 3707897Shestness@cs.utexas.edu } 3717897Shestness@cs.utexas.edu 3727897Shestness@cs.utexas.edu return false; 3737897Shestness@cs.utexas.edu} 3747897Shestness@cs.utexas.edu