Created new M5 instruction to allow an integer parameter (init_param) to be specified...
[gem5.git] / base / str.cc
1 /*
2 * Copyright (c) 2003 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <iostream>
30
31 #include <string.h>
32 #include <ctype.h>
33
34 #include <string>
35 #include <vector>
36
37 #include "base/intmath.hh"
38 #include "base/str.hh"
39
40 using namespace std;
41
42 void
43 tokenize(vector<string>& v, const string &s, char token, bool ignore)
44 {
45 string::size_type first = 0;
46 string::size_type last = s.find_first_of(token);
47
48 if (ignore) {
49 if (last == first) {
50 while (last == first)
51 last = s.find_first_of(token, ++first);
52
53 if (last == string::npos) {
54 v.push_back(s);
55 return;
56 }
57 }
58 }
59
60 while (last != string::npos) {
61 v.push_back(s.substr(first, last - first));
62
63 if (ignore) {
64 first = s.find_first_not_of(token, last + 1);
65
66 if (first == string::npos)
67 return;
68 } else
69 first = last + 1;
70
71 last = s.find_first_of(token, first);
72 }
73
74 v.push_back(s.substr(first));
75 }
76
77 template <class T>
78 inline bool
79 __to_number(string value, T &retval)
80 {
81 static const T maxnum = ((T)-1);
82 static const bool sign = maxnum < 0;
83 static const T hexmax = maxnum & (((T)1 << (sizeof(T) * 8 - 4)) - 1);
84 static const T octmax = maxnum & (((T)1 << (sizeof(T) * 8 - 3)) - 1);
85 static const T signmax =
86 (sign) ? maxnum & (((T)1 << (sizeof(T) * 8 - 1)) - 1) : maxnum;
87 static const T decmax = signmax / 10 - 1;
88
89 #if 0
90 cout << "maxnum = 0x" << hex << maxnum << "\n"
91 << "sign = 0x" << hex << sign << "\n"
92 << "hexmax = 0x" << hex << hexmax << "\n"
93 << "octmax = 0x" << hex << octmax << "\n"
94 << "signmax = 0x" << hex << signmax << "\n"
95 << "decmax = 0x" << hex << decmax << "\n";
96 #endif
97
98 eat_white(value);
99
100 bool negative = false;
101 bool hex = false;
102 bool oct = false;
103 int last = value.size() - 1;
104 retval = 0;
105 int i = 0;
106
107 char c = value[i];
108 if (!IsDec(c)) {
109 if (c == '-' && sign)
110 negative = true;
111 else
112 return false;
113 }
114 else {
115 retval += c - '0';
116 if (last == 0) return true;
117 }
118
119 if (c == '0')
120 oct = true;
121
122 c = value[++i];
123 if (oct) {
124 if (sign && negative)
125 return false;
126
127 if (!IsOct(c)) {
128 if (c == 'X' || c == 'x') {
129 hex = true;
130 oct = false;
131 } else
132 return false;
133 }
134 else
135 retval += c - '0';
136 } else if (!IsDec(c))
137 goto multiply;
138 else {
139 if (sign && negative && c == '0')
140 return false;
141
142 retval *= 10;
143 retval += c - '0';
144 if (last == 1) {
145 if (sign && negative) retval = -retval;
146 return true;
147 }
148 }
149
150 if (hex) {
151 if (last == 1)
152 return false;
153
154 for (i = 2; i <= last ; i++) {
155 c = value[i];
156 if (!IsHex(c))
157 return false;
158
159 if (retval > hexmax) return false;
160 retval *= 16;
161 retval += Hex2Int(c);
162 }
163 return true;
164 } else if (oct) {
165 for (i = 2; i <= last ; i++) {
166 c = value[i];
167 if (!IsOct(c))
168 return false;
169
170 if (retval > octmax) return false;
171 retval *= 8;
172 retval += (c - '0');
173 }
174 return true;
175 }
176
177 for (i = 2; i < last ; i++) {
178 c = value[i];
179 if (!IsDec(c))
180 goto multiply;
181
182 if (retval > decmax) return false;
183 retval *= 10;
184 retval += c - '0';
185 if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1))))
186 return false;
187 }
188
189 c = value[last];
190 if (IsDec(c)) {
191
192 if (retval > decmax) return false;
193 retval *= 10;
194 retval += c - '0';
195 if (sign && negative) {
196 if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) &&
197 retval >= (T)-signmax)
198 return false;
199 retval = -retval;
200 }
201 else
202 if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1))))
203 return false;
204 return true;
205 }
206
207 multiply:
208 signed long long mult = 1;
209 T val;
210 switch (c) {
211 case 'k':
212 case 'K':
213 if (i != last) return false;
214 mult = 1024;
215 val = signmax / mult;
216 break;
217 case 'm':
218 case 'M':
219 if (i != last) return false;
220 mult = 1024 * 1024;
221 val = signmax / mult;
222 break;
223 case 'g':
224 case 'G':
225 if (i != last) return false;
226 mult = 1024 * 1024 * 1024;
227 val = signmax / mult;
228 break;
229 case 'e':
230 case 'E':
231 if (i >= last) return false;
232
233 mult = 0;
234 for (i++; i <= last; i++) {
235 c = value[i];
236 if (!IsDec(c))
237 return false;
238
239 mult *= 10;
240 mult += c - '0';
241 }
242
243 for (i = 0; i < mult; i++) {
244 if (retval > signmax / 10)
245 return false;
246 retval *= 10;
247 if (sign && (retval & ((T)1 << (sizeof(T) * 8 - 1))))
248 return false;
249 }
250 if (sign && negative) {
251 if ((retval & ((T)1 << (sizeof(T) * 8 - 1))) &&
252 retval >= (T)-signmax)
253 return false;
254 retval = -retval;
255 }
256 else
257 if (sign && (retval & ((T)1 << ((sizeof(T) * 8) - 1))))
258 return false;
259
260 return true;
261
262 default:
263 return false;
264 }
265
266 if (sign && negative)
267 return false;
268
269 if (mult > (unsigned long long)signmax)
270 return false;
271
272 if (retval > val)
273 return false;
274
275 retval *= mult;
276
277 return true;
278 }
279
280 #define STN(type) \
281 template<> \
282 bool to_number<type>(const string &value, type &retval) \
283 { return __to_number(value, retval); }
284
285 STN(unsigned long long);
286 STN(signed long long);
287 STN(unsigned long);
288 STN(signed long);
289 STN(unsigned int);
290 STN(signed int);
291 STN(unsigned short);
292 STN(signed short);
293 STN(unsigned char);
294 STN(signed char);
295
296 template<>
297 bool to_number<bool>(const string &value, bool &retval)
298 {
299 string lowered = to_lower(value);
300
301 if (value == "0") {
302 retval = false;
303 return true;
304 }
305
306 if (value == "1"){
307 retval = true;
308 return true;
309 }
310
311 if (lowered == "false") {
312 retval = false;
313 return true;
314 }
315
316 if (lowered == "true"){
317 retval = true;
318 return true;
319 }
320
321 if (lowered == "no") {
322 retval = false;
323 return true;
324 }
325
326 if (lowered == "yes"){
327 retval = true;
328 return true;
329 }
330
331 return false;
332 }