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