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