str.cc revision 1380
15361Srstrong@cs.ucsd.edu/* 23671Sbinkertn@umich.edu * Copyright (c) 2001-2003 The Regents of The University of Michigan 33671Sbinkertn@umich.edu * All rights reserved. 43671Sbinkertn@umich.edu * 53671Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without 63671Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are 73671Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright 83671Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer; 93671Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright 103671Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the 113671Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution; 123671Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its 133671Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from 143671Sbinkertn@umich.edu * this software without specific prior written permission. 153671Sbinkertn@umich.edu * 163671Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173671Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183671Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193671Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203671Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213671Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223671Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233671Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243671Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253671Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263671Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273671Sbinkertn@umich.edu */ 283671Sbinkertn@umich.edu 2912564Sgabeblack@google.com#include <iostream> 3012564Sgabeblack@google.com 313671Sbinkertn@umich.edu#include <string.h> 323671Sbinkertn@umich.edu#include <ctype.h> 333671Sbinkertn@umich.edu 343671Sbinkertn@umich.edu#include <string> 353671Sbinkertn@umich.edu#include <vector> 366028Ssteve.reinhardt@amd.com 373671Sbinkertn@umich.edu#include "base/intmath.hh" 383671Sbinkertn@umich.edu#include "base/str.hh" 393671Sbinkertn@umich.edu 403671Sbinkertn@umich.eduusing namespace std; 413671Sbinkertn@umich.edu 423671Sbinkertn@umich.edubool 433671Sbinkertn@umich.edusplit_first(const string &s, string &lhs, string &rhs, char c) 443671Sbinkertn@umich.edu{ 453671Sbinkertn@umich.edu string::size_type offset = s.find(c); 463671Sbinkertn@umich.edu if (offset == string::npos) { 473671Sbinkertn@umich.edu lhs = s; 483671Sbinkertn@umich.edu rhs = ""; 493671Sbinkertn@umich.edu return false; 503671Sbinkertn@umich.edu } 513671Sbinkertn@umich.edu 523671Sbinkertn@umich.edu lhs = s.substr(0, offset); 533671Sbinkertn@umich.edu rhs = s.substr(offset + 1); 543671Sbinkertn@umich.edu return true; 553671Sbinkertn@umich.edu} 563671Sbinkertn@umich.edu 573671Sbinkertn@umich.edubool 583671Sbinkertn@umich.edusplit_last(const string &s, string &lhs, string &rhs, char c) 593671Sbinkertn@umich.edu{ 603671Sbinkertn@umich.edu string::size_type offset = s.rfind(c); 613671Sbinkertn@umich.edu if (offset == string::npos) { 623671Sbinkertn@umich.edu lhs = s; 633671Sbinkertn@umich.edu rhs = ""; 643671Sbinkertn@umich.edu return false; 653671Sbinkertn@umich.edu } 663671Sbinkertn@umich.edu 673671Sbinkertn@umich.edu lhs = s.substr(0, offset); 683671Sbinkertn@umich.edu rhs = s.substr(offset + 1); 693671Sbinkertn@umich.edu return true; 703671Sbinkertn@umich.edu} 713671Sbinkertn@umich.edu 723671Sbinkertn@umich.eduvoid 733671Sbinkertn@umich.edutokenize(vector<string>& v, const string &s, char token, bool ignore) 743671Sbinkertn@umich.edu{ 753671Sbinkertn@umich.edu string::size_type first = 0; 763671Sbinkertn@umich.edu string::size_type last = s.find_first_of(token); 773671Sbinkertn@umich.edu 783671Sbinkertn@umich.edu if (ignore) { 793671Sbinkertn@umich.edu if (last == first) { 803671Sbinkertn@umich.edu while (last == first) 813671Sbinkertn@umich.edu last = s.find_first_of(token, ++first); 823671Sbinkertn@umich.edu 833671Sbinkertn@umich.edu if (last == string::npos) { 843671Sbinkertn@umich.edu v.push_back(s); 853671Sbinkertn@umich.edu return; 863671Sbinkertn@umich.edu } 873671Sbinkertn@umich.edu } 883671Sbinkertn@umich.edu } 893671Sbinkertn@umich.edu 905361Srstrong@cs.ucsd.edu while (last != string::npos) { 915361Srstrong@cs.ucsd.edu v.push_back(s.substr(first, last - first)); 925361Srstrong@cs.ucsd.edu 933671Sbinkertn@umich.edu if (ignore) { 943671Sbinkertn@umich.edu first = s.find_first_not_of(token, last + 1); 953671Sbinkertn@umich.edu 963671Sbinkertn@umich.edu if (first == string::npos) 973671Sbinkertn@umich.edu return; 983671Sbinkertn@umich.edu } else 993671Sbinkertn@umich.edu first = last + 1; 1003671Sbinkertn@umich.edu 1013671Sbinkertn@umich.edu last = s.find_first_of(token, first); 1023671Sbinkertn@umich.edu } 1033671Sbinkertn@umich.edu 1043671Sbinkertn@umich.edu v.push_back(s.substr(first)); 1053671Sbinkertn@umich.edu} 1063671Sbinkertn@umich.edu 1073671Sbinkertn@umich.edu/** 1083671Sbinkertn@umich.edu * @todo This function will not handle the smallest negative decimal 1093671Sbinkertn@umich.edu * value for a signed type 1103671Sbinkertn@umich.edu */ 1113671Sbinkertn@umich.edu 1124116Sgblack@eecs.umich.edutemplate <class T> 1134116Sgblack@eecs.umich.eduinline bool 1143671Sbinkertn@umich.edu__to_number(string value, T &retval) 1153671Sbinkertn@umich.edu{ 1163671Sbinkertn@umich.edu static const T maxnum = ((T)-1); 1173671Sbinkertn@umich.edu static const bool sign = maxnum < 0; 1183671Sbinkertn@umich.edu static const int bits = sizeof(T) * 8; 1193671Sbinkertn@umich.edu static const T hexmax = maxnum & (((T)1 << (bits - 4 - sign)) - 1); 1203671Sbinkertn@umich.edu static const T octmax = maxnum & (((T)1 << (bits - 3 - sign)) - 1); 1213671Sbinkertn@umich.edu static const T signmax = 1223671Sbinkertn@umich.edu (sign) ? maxnum & (((T)1 << (bits - 1)) - 1) : maxnum; 1233671Sbinkertn@umich.edu static const T decmax = signmax / 10; 1243671Sbinkertn@umich.edu 1253671Sbinkertn@umich.edu#if 0 1263671Sbinkertn@umich.edu cout << "maxnum = 0x" << hex << (unsigned long long)maxnum << "\n" 1273671Sbinkertn@umich.edu << "sign = 0x" << hex << (unsigned long long)sign << "\n" 1283671Sbinkertn@umich.edu << "hexmax = 0x" << hex << (unsigned long long)hexmax << "\n" 1293671Sbinkertn@umich.edu << "octmax = 0x" << hex << (unsigned long long)octmax << "\n" 1303671Sbinkertn@umich.edu << "signmax = 0x" << hex << (unsigned long long)signmax << "\n" 1313671Sbinkertn@umich.edu << "decmax = 0x" << hex << (unsigned long long)decmax << "\n"; 1323671Sbinkertn@umich.edu#endif 1333671Sbinkertn@umich.edu 1343671Sbinkertn@umich.edu eat_white(value); 1353671Sbinkertn@umich.edu 13611851Sbrandon.potter@amd.com bool negative = false; 13711851Sbrandon.potter@amd.com bool hex = false; 1383671Sbinkertn@umich.edu bool oct = false; 1394555Sbinkertn@umich.edu int last = value.size() - 1; 1403671Sbinkertn@umich.edu retval = 0; 1413671Sbinkertn@umich.edu int i = 0; 1423671Sbinkertn@umich.edu 1433671Sbinkertn@umich.edu char c = value[i]; 1443671Sbinkertn@umich.edu if (!IsDec(c)) { 1455378Ssaidi@eecs.umich.edu if (c == '-' && sign) 1465378Ssaidi@eecs.umich.edu negative = true; 1473671Sbinkertn@umich.edu else 1483671Sbinkertn@umich.edu return false; 1493671Sbinkertn@umich.edu } 1503671Sbinkertn@umich.edu else { 1513671Sbinkertn@umich.edu retval += c - '0'; 15211851Sbrandon.potter@amd.com if (last == 0) return true; 15311851Sbrandon.potter@amd.com } 1543671Sbinkertn@umich.edu 1553671Sbinkertn@umich.edu if (c == '0') 15611851Sbrandon.potter@amd.com oct = true; 1573671Sbinkertn@umich.edu 1585361Srstrong@cs.ucsd.edu c = value[++i]; 1593671Sbinkertn@umich.edu if (oct) { 1608246Snate@binkert.org if (sign && negative) 1613671Sbinkertn@umich.edu return false; 1623671Sbinkertn@umich.edu 1633671Sbinkertn@umich.edu if (!IsOct(c)) { 1643671Sbinkertn@umich.edu if (c == 'X' || c == 'x') { 1653671Sbinkertn@umich.edu hex = true; 1663671Sbinkertn@umich.edu oct = false; 1673671Sbinkertn@umich.edu } else 16811851Sbrandon.potter@amd.com return false; 16911851Sbrandon.potter@amd.com } 17011851Sbrandon.potter@amd.com else 1713671Sbinkertn@umich.edu retval += c - '0'; 1723671Sbinkertn@umich.edu } else if (!IsDec(c)) 1733671Sbinkertn@umich.edu goto multiply; 1743671Sbinkertn@umich.edu else { 1753671Sbinkertn@umich.edu if (sign && negative && c == '0') 1763671Sbinkertn@umich.edu return false; 1773671Sbinkertn@umich.edu 1783671Sbinkertn@umich.edu retval *= 10; 1793671Sbinkertn@umich.edu retval += c - '0'; 1803671Sbinkertn@umich.edu if (last == 1) { 1813671Sbinkertn@umich.edu if (sign && negative) retval = -retval; 1823671Sbinkertn@umich.edu return true; 1833671Sbinkertn@umich.edu } 1843671Sbinkertn@umich.edu } 1853671Sbinkertn@umich.edu 1863671Sbinkertn@umich.edu if (hex) { 1873671Sbinkertn@umich.edu if (last == 1) 1883671Sbinkertn@umich.edu return false; 1895361Srstrong@cs.ucsd.edu 1903671Sbinkertn@umich.edu for (i = 2; i <= last ; i++) { 1913671Sbinkertn@umich.edu c = value[i]; 1923671Sbinkertn@umich.edu if (!IsHex(c)) 1933671Sbinkertn@umich.edu return false; 1943671Sbinkertn@umich.edu 1955361Srstrong@cs.ucsd.edu if (retval > hexmax) return false; 1963671Sbinkertn@umich.edu retval *= 16; 1973671Sbinkertn@umich.edu retval += Hex2Int(c); 1983671Sbinkertn@umich.edu } 1993671Sbinkertn@umich.edu return true; 2003671Sbinkertn@umich.edu } else if (oct) { 2015361Srstrong@cs.ucsd.edu for (i = 2; i <= last ; i++) { 2023671Sbinkertn@umich.edu c = value[i]; 2033671Sbinkertn@umich.edu if (!IsOct(c)) 2043671Sbinkertn@umich.edu return false; 2053671Sbinkertn@umich.edu 2063671Sbinkertn@umich.edu if (retval > octmax) return false; 2073671Sbinkertn@umich.edu retval *= 8; 2083671Sbinkertn@umich.edu retval += (c - '0'); 2093671Sbinkertn@umich.edu } 2103671Sbinkertn@umich.edu return true; 2113671Sbinkertn@umich.edu } 2123671Sbinkertn@umich.edu 2133671Sbinkertn@umich.edu for (i = 2; i < last ; i++) { 2143671Sbinkertn@umich.edu c = value[i]; 2153671Sbinkertn@umich.edu if (!IsDec(c)) 2163671Sbinkertn@umich.edu goto multiply; 2173671Sbinkertn@umich.edu 2183671Sbinkertn@umich.edu if (retval > decmax) return false; 2193671Sbinkertn@umich.edu bool atmax = retval == decmax; 2203671Sbinkertn@umich.edu retval *= 10; 2213671Sbinkertn@umich.edu retval += c - '0'; 2223671Sbinkertn@umich.edu if (atmax && retval < decmax) return false; 2233671Sbinkertn@umich.edu if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 2243671Sbinkertn@umich.edu return false; 2253671Sbinkertn@umich.edu } 2263671Sbinkertn@umich.edu 2273671Sbinkertn@umich.edu c = value[last]; 2283671Sbinkertn@umich.edu if (IsDec(c)) { 2293671Sbinkertn@umich.edu 2303671Sbinkertn@umich.edu if (retval > decmax) return false; 2313671Sbinkertn@umich.edu bool atmax = retval == decmax; 2323671Sbinkertn@umich.edu retval *= 10; 2333671Sbinkertn@umich.edu retval += c - '0'; 2343671Sbinkertn@umich.edu if (atmax && retval < decmax) return false; 2353671Sbinkertn@umich.edu if (sign && negative) { 2363671Sbinkertn@umich.edu if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 2373671Sbinkertn@umich.edu retval >= (T)-signmax) 2383671Sbinkertn@umich.edu return false; 2393671Sbinkertn@umich.edu retval = -retval; 2403671Sbinkertn@umich.edu } 2413671Sbinkertn@umich.edu else 2423671Sbinkertn@umich.edu if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 2433671Sbinkertn@umich.edu return false; 2443671Sbinkertn@umich.edu return true; 2453671Sbinkertn@umich.edu } 2463671Sbinkertn@umich.edu 2473671Sbinkertn@umich.edu multiply: 2483671Sbinkertn@umich.edu signed long long mult = 1; 2493671Sbinkertn@umich.edu T val; 2503671Sbinkertn@umich.edu switch (c) { 2513671Sbinkertn@umich.edu case 'k': 2523671Sbinkertn@umich.edu case 'K': 2533671Sbinkertn@umich.edu if (i != last) return false; 2545361Srstrong@cs.ucsd.edu mult = 1024; 2553671Sbinkertn@umich.edu val = signmax / mult; 2563671Sbinkertn@umich.edu break; 2573671Sbinkertn@umich.edu case 'm': 2583671Sbinkertn@umich.edu case 'M': 2593671Sbinkertn@umich.edu if (i != last) return false; 2603671Sbinkertn@umich.edu mult = 1024 * 1024; 2613671Sbinkertn@umich.edu val = signmax / mult; 2623671Sbinkertn@umich.edu break; 2633671Sbinkertn@umich.edu case 'g': 2643671Sbinkertn@umich.edu case 'G': 2653671Sbinkertn@umich.edu if (i != last) return false; 2663671Sbinkertn@umich.edu mult = 1024 * 1024 * 1024; 2673671Sbinkertn@umich.edu val = signmax / mult; 2685361Srstrong@cs.ucsd.edu break; 2693671Sbinkertn@umich.edu case 'e': 2703671Sbinkertn@umich.edu case 'E': 2713671Sbinkertn@umich.edu if (i >= last) return false; 2723671Sbinkertn@umich.edu 2733671Sbinkertn@umich.edu mult = 0; 2745361Srstrong@cs.ucsd.edu for (i++; i <= last; i++) { 2753671Sbinkertn@umich.edu c = value[i]; 2763671Sbinkertn@umich.edu if (!IsDec(c)) 2773671Sbinkertn@umich.edu return false; 2783671Sbinkertn@umich.edu 2793671Sbinkertn@umich.edu mult *= 10; 2803671Sbinkertn@umich.edu mult += c - '0'; 2813671Sbinkertn@umich.edu } 2825361Srstrong@cs.ucsd.edu 2833671Sbinkertn@umich.edu for (i = 0; i < mult; i++) { 2843671Sbinkertn@umich.edu if (retval > signmax / 10) 2853671Sbinkertn@umich.edu return false; 2863671Sbinkertn@umich.edu retval *= 10; 2873671Sbinkertn@umich.edu if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 2885361Srstrong@cs.ucsd.edu return false; 2893671Sbinkertn@umich.edu } 2903671Sbinkertn@umich.edu if (sign && negative) { 2913671Sbinkertn@umich.edu if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 2923671Sbinkertn@umich.edu retval >= (T)-signmax) 2933671Sbinkertn@umich.edu return false; 2945361Srstrong@cs.ucsd.edu retval = -retval; 2953671Sbinkertn@umich.edu } 2963671Sbinkertn@umich.edu else 2973671Sbinkertn@umich.edu if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 2983671Sbinkertn@umich.edu return false; 2993671Sbinkertn@umich.edu 3005361Srstrong@cs.ucsd.edu return true; 3013671Sbinkertn@umich.edu 3023671Sbinkertn@umich.edu default: 3033671Sbinkertn@umich.edu return false; 3043671Sbinkertn@umich.edu } 3053671Sbinkertn@umich.edu 3063671Sbinkertn@umich.edu if (sign && negative) 3073671Sbinkertn@umich.edu return false; 3083671Sbinkertn@umich.edu 3093671Sbinkertn@umich.edu if (mult > (unsigned long long)signmax) 3103671Sbinkertn@umich.edu return false; 3113671Sbinkertn@umich.edu 3123671Sbinkertn@umich.edu if (retval > val) 3133671Sbinkertn@umich.edu return false; 3143671Sbinkertn@umich.edu 3153671Sbinkertn@umich.edu retval *= mult; 3163671Sbinkertn@umich.edu 3173671Sbinkertn@umich.edu return true; 3183671Sbinkertn@umich.edu} 3193671Sbinkertn@umich.edu 3205361Srstrong@cs.ucsd.edu#define STN(type) \ 3213671Sbinkertn@umich.edutemplate<> \ 3223671Sbinkertn@umich.edubool to_number<type>(const string &value, type &retval) \ 3233671Sbinkertn@umich.edu{ return __to_number(value, retval); } 3243671Sbinkertn@umich.edu 3253671Sbinkertn@umich.eduSTN(unsigned long long); 3263671Sbinkertn@umich.eduSTN(signed long long); 3273671Sbinkertn@umich.eduSTN(unsigned long); 3283671Sbinkertn@umich.eduSTN(signed long); 3295361Srstrong@cs.ucsd.eduSTN(unsigned int); 3303671Sbinkertn@umich.eduSTN(signed int); 3313671Sbinkertn@umich.eduSTN(unsigned short); 3323671Sbinkertn@umich.eduSTN(signed short); 3333671Sbinkertn@umich.eduSTN(unsigned char); 3343671Sbinkertn@umich.eduSTN(signed char); 3355361Srstrong@cs.ucsd.edu 3363671Sbinkertn@umich.edutemplate<> 3373671Sbinkertn@umich.edubool to_number<bool>(const string &value, bool &retval) 3383671Sbinkertn@umich.edu{ 3393671Sbinkertn@umich.edu string lowered = to_lower(value); 3403671Sbinkertn@umich.edu 3413671Sbinkertn@umich.edu if (value == "0") { 3423671Sbinkertn@umich.edu retval = false; 3435361Srstrong@cs.ucsd.edu return true; 3443671Sbinkertn@umich.edu } 3453671Sbinkertn@umich.edu 3463671Sbinkertn@umich.edu if (value == "1"){ 3473671Sbinkertn@umich.edu retval = true; 3483671Sbinkertn@umich.edu return true; 3495361Srstrong@cs.ucsd.edu } 3503671Sbinkertn@umich.edu 3513671Sbinkertn@umich.edu if (lowered == "false") { 3523671Sbinkertn@umich.edu retval = false; 3533671Sbinkertn@umich.edu return true; 3543671Sbinkertn@umich.edu } 3553671Sbinkertn@umich.edu 3563671Sbinkertn@umich.edu if (lowered == "true"){ 3573671Sbinkertn@umich.edu retval = true; 3583671Sbinkertn@umich.edu return true; 3593671Sbinkertn@umich.edu } 3603671Sbinkertn@umich.edu 3613671Sbinkertn@umich.edu if (lowered == "no") { 3623671Sbinkertn@umich.edu retval = false; 3633671Sbinkertn@umich.edu return true; 3643671Sbinkertn@umich.edu } 3653671Sbinkertn@umich.edu 3665361Srstrong@cs.ucsd.edu if (lowered == "yes"){ 3673671Sbinkertn@umich.edu retval = true; 3683671Sbinkertn@umich.edu return true; 3693671Sbinkertn@umich.edu } 3703671Sbinkertn@umich.edu 3713671Sbinkertn@umich.edu return false; 3723671Sbinkertn@umich.edu} 3733671Sbinkertn@umich.edu