str.cc revision 239
19243SN/A/* 210889Sandreas.hansson@arm.com * Copyright (c) 2003 The Regents of The University of Michigan 39243SN/A * All rights reserved. 49243SN/A * 59243SN/A * Redistribution and use in source and binary forms, with or without 69243SN/A * modification, are permitted provided that the following conditions are 79243SN/A * met: redistributions of source code must retain the above copyright 89243SN/A * notice, this list of conditions and the following disclaimer; 99243SN/A * redistributions in binary form must reproduce the above copyright 109243SN/A * notice, this list of conditions and the following disclaimer in the 119243SN/A * documentation and/or other materials provided with the distribution; 129243SN/A * neither the name of the copyright holders nor the names of its 139243SN/A * contributors may be used to endorse or promote products derived from 149831SN/A * this software without specific prior written permission. 159831SN/A * 169831SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 179243SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 189243SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 199243SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 209243SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 219243SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 229243SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239243SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249243SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259243SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269243SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279243SN/A */ 289243SN/A 299243SN/A#include <iostream> 309243SN/A 319243SN/A#include <string.h> 329243SN/A#include <ctype.h> 339243SN/A 349243SN/A#include <string> 359243SN/A#include <vector> 369243SN/A 379243SN/A#include "base/intmath.hh" 389243SN/A#include "base/str.hh" 399243SN/A 409243SN/Ausing namespace std; 419243SN/A 429967SN/Avoid 4310618SOmar.Naji@arm.comtokenize(vector<string>& v, const string &s, char token, bool ignore) 449243SN/A{ 459243SN/A string::size_type first = 0; 4610146Sandreas.hansson@arm.com string::size_type last = s.find_first_of(token); 479356SN/A 4810146Sandreas.hansson@arm.com if (ignore) { 4910247Sandreas.hansson@arm.com if (last == first) { 5010208Sandreas.hansson@arm.com while (last == first) 519352SN/A last = s.find_first_of(token, ++first); 5210146Sandreas.hansson@arm.com 539814SN/A if (last == string::npos) { 549243SN/A v.push_back(s); 559243SN/A return; 5610432SOmar.Naji@arm.com } 579243SN/A } 5810146Sandreas.hansson@arm.com } 599243SN/A 6010619Sandreas.hansson@arm.com while (last != string::npos) { 619243SN/A v.push_back(s.substr(first, last - first)); 6210211Sandreas.hansson@arm.com 6310618SOmar.Naji@arm.com if (ignore) { 6410208Sandreas.hansson@arm.com first = s.find_first_not_of(token, last + 1); 6510489SOmar.Naji@arm.com 669831SN/A if (first == string::npos) 679831SN/A return; 689831SN/A } else 699831SN/A first = last + 1; 709831SN/A 7110140SN/A last = s.find_first_of(token, first); 7210646Sandreas.hansson@arm.com } 739243SN/A 7410394Swendy.elsasser@arm.com v.push_back(s.substr(first)); 7510394Swendy.elsasser@arm.com} 769566SN/A 779243SN/A/** 789243SN/A * @todo This function will not handle the smallest negative decimal 7910140SN/A * value for a signed type 8010140SN/A */ 8110147Sandreas.hansson@arm.com 8210147Sandreas.hansson@arm.comtemplate <class T> 8310393Swendy.elsasser@arm.cominline bool 8410394Swendy.elsasser@arm.com__to_number(string value, T &retval) 8510394Swendy.elsasser@arm.com{ 8610394Swendy.elsasser@arm.com static const T maxnum = ((T)-1); 879243SN/A static const bool sign = maxnum < 0; 889243SN/A static const int bits = sizeof(T) * 8; 8910141SN/A static const T hexmax = maxnum & (((T)1 << (bits - 4 - sign)) - 1); 909726SN/A static const T octmax = maxnum & (((T)1 << (bits - 3 - sign)) - 1); 919726SN/A static const T signmax = 9210618SOmar.Naji@arm.com (sign) ? maxnum & (((T)1 << (bits - 1)) - 1) : maxnum; 9310618SOmar.Naji@arm.com static const T decmax = signmax / 10; 949243SN/A 9510620Sandreas.hansson@arm.com#if 0 9610620Sandreas.hansson@arm.com cout << "maxnum = 0x" << hex << (unsigned long long)maxnum << "\n" 9710620Sandreas.hansson@arm.com << "sign = 0x" << hex << (unsigned long long)sign << "\n" 9810620Sandreas.hansson@arm.com << "hexmax = 0x" << hex << (unsigned long long)hexmax << "\n" 9910620Sandreas.hansson@arm.com << "octmax = 0x" << hex << (unsigned long long)octmax << "\n" 10010889Sandreas.hansson@arm.com << "signmax = 0x" << hex << (unsigned long long)signmax << "\n" 10110889Sandreas.hansson@arm.com << "decmax = 0x" << hex << (unsigned long long)decmax << "\n"; 10210889Sandreas.hansson@arm.com#endif 10310618SOmar.Naji@arm.com 10410618SOmar.Naji@arm.com eat_white(value); 10510618SOmar.Naji@arm.com 10610432SOmar.Naji@arm.com bool negative = false; 10710618SOmar.Naji@arm.com bool hex = false; 10810618SOmar.Naji@arm.com bool oct = false; 10910618SOmar.Naji@arm.com int last = value.size() - 1; 11010432SOmar.Naji@arm.com retval = 0; 11110246Sandreas.hansson@arm.com int i = 0; 11210618SOmar.Naji@arm.com 11310561SOmar.Naji@arm.com char c = value[i]; 11410561SOmar.Naji@arm.com if (!IsDec(c)) { 11510561SOmar.Naji@arm.com if (c == '-' && sign) 11610394Swendy.elsasser@arm.com negative = true; 11710394Swendy.elsasser@arm.com else 11810394Swendy.elsasser@arm.com return false; 11910394Swendy.elsasser@arm.com } 12010394Swendy.elsasser@arm.com else { 12110394Swendy.elsasser@arm.com retval += c - '0'; 12210394Swendy.elsasser@arm.com if (last == 0) return true; 12310394Swendy.elsasser@arm.com } 12410618SOmar.Naji@arm.com 12510394Swendy.elsasser@arm.com if (c == '0') 12610394Swendy.elsasser@arm.com oct = true; 12710618SOmar.Naji@arm.com 12810394Swendy.elsasser@arm.com c = value[++i]; 12910246Sandreas.hansson@arm.com if (oct) { 13010246Sandreas.hansson@arm.com if (sign && negative) 13110246Sandreas.hansson@arm.com return false; 13210140SN/A 13310140SN/A if (!IsOct(c)) { 13410140SN/A if (c == 'X' || c == 'x') { 13510140SN/A hex = true; 13610140SN/A oct = false; 1379243SN/A } else 1389243SN/A return false; 1399567SN/A } 1409243SN/A else 14110489SOmar.Naji@arm.com retval += c - '0'; 14210489SOmar.Naji@arm.com } else if (!IsDec(c)) 14310489SOmar.Naji@arm.com goto multiply; 14410489SOmar.Naji@arm.com else { 14510489SOmar.Naji@arm.com if (sign && negative && c == '0') 14610489SOmar.Naji@arm.com return false; 14710489SOmar.Naji@arm.com 14810489SOmar.Naji@arm.com retval *= 10; 14910489SOmar.Naji@arm.com retval += c - '0'; 15010489SOmar.Naji@arm.com if (last == 1) { 1519243SN/A if (sign && negative) retval = -retval; 1529243SN/A return true; 1539831SN/A } 1549831SN/A } 1559831SN/A 1569831SN/A if (hex) { 1579831SN/A if (last == 1) 1589243SN/A return false; 15910207Sandreas.hansson@arm.com 16010207Sandreas.hansson@arm.com for (i = 2; i <= last ; i++) { 16110207Sandreas.hansson@arm.com c = value[i]; 16210207Sandreas.hansson@arm.com if (!IsHex(c)) 16310207Sandreas.hansson@arm.com return false; 16410394Swendy.elsasser@arm.com 16510394Swendy.elsasser@arm.com if (retval > hexmax) return false; 16610394Swendy.elsasser@arm.com retval *= 16; 16710394Swendy.elsasser@arm.com retval += Hex2Int(c); 16810394Swendy.elsasser@arm.com } 16910394Swendy.elsasser@arm.com return true; 17010394Swendy.elsasser@arm.com } else if (oct) { 17110394Swendy.elsasser@arm.com for (i = 2; i <= last ; i++) { 17210394Swendy.elsasser@arm.com c = value[i]; 17310394Swendy.elsasser@arm.com if (!IsOct(c)) 17410394Swendy.elsasser@arm.com return false; 17510394Swendy.elsasser@arm.com 17610394Swendy.elsasser@arm.com if (retval > octmax) return false; 17710394Swendy.elsasser@arm.com retval *= 8; 17810394Swendy.elsasser@arm.com retval += (c - '0'); 17910394Swendy.elsasser@arm.com } 18010394Swendy.elsasser@arm.com return true; 18110394Swendy.elsasser@arm.com } 18210394Swendy.elsasser@arm.com 18310394Swendy.elsasser@arm.com for (i = 2; i < last ; i++) { 18410394Swendy.elsasser@arm.com c = value[i]; 18510394Swendy.elsasser@arm.com if (!IsDec(c)) 18610561SOmar.Naji@arm.com goto multiply; 18710561SOmar.Naji@arm.com 18810394Swendy.elsasser@arm.com if (retval > decmax) return false; 18910394Swendy.elsasser@arm.com bool atmax = retval == decmax; 19010394Swendy.elsasser@arm.com retval *= 10; 19110394Swendy.elsasser@arm.com retval += c - '0'; 19210394Swendy.elsasser@arm.com if (atmax && retval < decmax) return false; 19310394Swendy.elsasser@arm.com if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 1949243SN/A return false; 1959243SN/A } 1969243SN/A 19710146Sandreas.hansson@arm.com c = value[last]; 19810140SN/A if (IsDec(c)) { 19910466Sandreas.hansson@arm.com 20010466Sandreas.hansson@arm.com if (retval > decmax) return false; 20110466Sandreas.hansson@arm.com bool atmax = retval == decmax; 20210146Sandreas.hansson@arm.com retval *= 10; 20310140SN/A retval += c - '0'; 20410140SN/A if (atmax && retval < decmax) return false; 20510140SN/A if (sign && negative) { 20610646Sandreas.hansson@arm.com if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 20710646Sandreas.hansson@arm.com retval >= (T)-signmax) 20810646Sandreas.hansson@arm.com return false; 20910646Sandreas.hansson@arm.com retval = -retval; 21010646Sandreas.hansson@arm.com } 21110646Sandreas.hansson@arm.com else 21210646Sandreas.hansson@arm.com if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 21310646Sandreas.hansson@arm.com return false; 21410646Sandreas.hansson@arm.com return true; 21510646Sandreas.hansson@arm.com } 21610646Sandreas.hansson@arm.com 21710646Sandreas.hansson@arm.com multiply: 21810646Sandreas.hansson@arm.com signed long long mult = 1; 21910646Sandreas.hansson@arm.com T val; 22010646Sandreas.hansson@arm.com switch (c) { 22110646Sandreas.hansson@arm.com case 'k': 22210646Sandreas.hansson@arm.com case 'K': 22310646Sandreas.hansson@arm.com if (i != last) return false; 22410646Sandreas.hansson@arm.com mult = 1024; 22510646Sandreas.hansson@arm.com val = signmax / mult; 22610646Sandreas.hansson@arm.com break; 22710646Sandreas.hansson@arm.com case 'm': 22810646Sandreas.hansson@arm.com case 'M': 22910646Sandreas.hansson@arm.com if (i != last) return false; 23010646Sandreas.hansson@arm.com mult = 1024 * 1024; 23110646Sandreas.hansson@arm.com val = signmax / mult; 23210646Sandreas.hansson@arm.com break; 23310646Sandreas.hansson@arm.com case 'g': 23410646Sandreas.hansson@arm.com case 'G': 23510646Sandreas.hansson@arm.com if (i != last) return false; 23610646Sandreas.hansson@arm.com mult = 1024 * 1024 * 1024; 23710646Sandreas.hansson@arm.com val = signmax / mult; 23810646Sandreas.hansson@arm.com break; 23910646Sandreas.hansson@arm.com case 'e': 24010646Sandreas.hansson@arm.com case 'E': 24110646Sandreas.hansson@arm.com if (i >= last) return false; 24210646Sandreas.hansson@arm.com 24310646Sandreas.hansson@arm.com mult = 0; 24410646Sandreas.hansson@arm.com for (i++; i <= last; i++) { 24510646Sandreas.hansson@arm.com c = value[i]; 24610140SN/A if (!IsDec(c)) 24710140SN/A return false; 24810140SN/A 24910146Sandreas.hansson@arm.com mult *= 10; 2509243SN/A mult += c - '0'; 25110619Sandreas.hansson@arm.com } 25210619Sandreas.hansson@arm.com 25310618SOmar.Naji@arm.com for (i = 0; i < mult; i++) { 25410619Sandreas.hansson@arm.com if (retval > signmax / 10) 25510619Sandreas.hansson@arm.com return false; 25610619Sandreas.hansson@arm.com retval *= 10; 25710619Sandreas.hansson@arm.com if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1)))) 25810619Sandreas.hansson@arm.com return false; 25910619Sandreas.hansson@arm.com } 26010619Sandreas.hansson@arm.com if (sign && negative) { 26110619Sandreas.hansson@arm.com if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) && 26210619Sandreas.hansson@arm.com retval >= (T)-signmax) 26310619Sandreas.hansson@arm.com return false; 26410619Sandreas.hansson@arm.com retval = -retval; 26510619Sandreas.hansson@arm.com } 26610619Sandreas.hansson@arm.com else 26710619Sandreas.hansson@arm.com if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1)))) 26810619Sandreas.hansson@arm.com return false; 26910618SOmar.Naji@arm.com 2709243SN/A return true; 2719243SN/A 2729243SN/A default: 27310146Sandreas.hansson@arm.com return false; 2749243SN/A } 2759243SN/A 2769243SN/A if (sign && negative) 2779243SN/A return false; 2789243SN/A 2799243SN/A if (mult > (unsigned long long)signmax) 2809243SN/A return false; 2819243SN/A 2829243SN/A if (retval > val) 2839243SN/A return false; 2849243SN/A 2859243SN/A retval *= mult; 2869243SN/A 2879243SN/A return true; 2889243SN/A} 2899243SN/A 29010146Sandreas.hansson@arm.com#define STN(type) \ 2919243SN/Atemplate<> \ 2929831SN/Abool to_number<type>(const string &value, type &retval) \ 2939831SN/A{ return __to_number(value, retval); } 2949831SN/A 2959243SN/ASTN(unsigned long long); 2969831SN/ASTN(signed long long); 2979831SN/ASTN(unsigned long); 2989243SN/ASTN(signed long); 2999243SN/ASTN(unsigned int); 3009243SN/ASTN(signed int); 30110146Sandreas.hansson@arm.comSTN(unsigned short); 3029243SN/ASTN(signed short); 3039831SN/ASTN(unsigned char); 3049831SN/ASTN(signed char); 3059831SN/A 3069243SN/Atemplate<> 3079243SN/Abool to_number<bool>(const string &value, bool &retval) 30810146Sandreas.hansson@arm.com{ 30910146Sandreas.hansson@arm.com string lowered = to_lower(value); 31010143SN/A 3119243SN/A if (value == "0") { 3129669SN/A retval = false; 31310136SN/A return true; 31410136SN/A } 3159243SN/A 3169967SN/A if (value == "1"){ 31710245Sandreas.hansson@arm.com retval = true; 31810245Sandreas.hansson@arm.com return true; 31910245Sandreas.hansson@arm.com } 3209243SN/A 32110286Sandreas.hansson@arm.com if (lowered == "false") { 32210286Sandreas.hansson@arm.com retval = false; 3239831SN/A return true; 3249243SN/A } 3259491SN/A 3269831SN/A if (lowered == "true"){ 32710136SN/A retval = true; 3289491SN/A return true; 3299491SN/A } 3309831SN/A 3319243SN/A if (lowered == "no") { 3329669SN/A retval = false; 3339566SN/A return true; 3349566SN/A } 3359669SN/A 3369669SN/A if (lowered == "yes"){ 3379669SN/A retval = true; 3389669SN/A return true; 3399669SN/A } 3409669SN/A 3419669SN/A return false; 3429669SN/A} 3439669SN/A