gem5  v22.1.0.0
str.test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 The Regents of the University of California
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include <gtest/gtest.h>
39 
40 #include <cstdint>
41 
42 #include "base/str.hh"
43 
44 using namespace gem5;
45 
46 /*
47  * str.cc has "eat_lead_white", "eat_end_white", and "eat_white" fucntions to
48  * remove leading and trailing whitespace. The following tests verify this
49  * behavior.
50  */
51 TEST(StrTest, EatLeadWhite)
52 {
53  std::string val = " hello there ";
55  EXPECT_EQ("hello there ", val);
56 }
57 
58 TEST(StrTest, EatLeadWhiteNoLeadingWhitespace)
59 {
60  std::string val = "hello there ";
62  EXPECT_EQ("hello there ", val);
63 }
64 
65 TEST(StrTest, EatEndWhite)
66 {
67  std::string val = " hello there ";
69  EXPECT_EQ(" hello there", val);
70 }
71 
72 TEST(StrTest, EatEndWhiteNoTrailingWhitespace)
73 {
74  std::string val = " hello there";
76  EXPECT_EQ(" hello there", val);
77 }
78 
79 TEST(StrTest, EatWhite)
80 {
81  std::string val = " hello there ";
82  eat_white(val);
83  EXPECT_EQ("hello there", val);
84 }
85 
86 TEST(StrTest, EatWhiteNoWhitespace)
87 {
88  std::string val = "hello there";
90  EXPECT_EQ("hello there", val);
91 }
92 
93 /*
94  * This tests checks that str.cc's "to_lower" function converts a string to
95  * lowercase.
96  */
97 TEST(StrTest, ToLower)
98 {
99  std::string val = "gOoDbYe FOO@barr!";
100  EXPECT_EQ("goodbye foo@barr!", to_lower(val));
101 }
102 
103 /*
104  * str.cc's "split_first" and "split_last" fucntions split a string on a
105  * character into two parts. "split_first" splits on the first instance of
106  * this character and "split_last" splits on the last instance of this
107  * character. The character itself is not included in either of the output
108  * right-hand side and left-hand side strings. If the character cannot be
109  * found in the string then the left-hand side string is equal to the input
110  * string and the right-hand side string is empty.
111  */
112 TEST(StrTest, SplitFirst)
113 {
114  std::string val = "abcdefg abcdefg";
115  std::string lhs;
116  std::string rhs;
117 
118  split_first(val , lhs, rhs, 'f');
119  EXPECT_EQ("abcdefg abcdefg", val);
120  EXPECT_EQ("abcde", lhs);
121  EXPECT_EQ("g abcdefg", rhs);
122 }
123 
124 TEST(StrTest, SplitFirstNoChar)
125 {
126  std::string val = "abcdefg abcdefg";
127  std::string lhs;
128  std::string rhs;
129 
130  split_first(val , lhs, rhs, 'h');
131  EXPECT_EQ("abcdefg abcdefg", val);
132  EXPECT_EQ("abcdefg abcdefg", lhs);
133  EXPECT_EQ("", rhs);
134 }
135 
136 TEST(StrTest, SplitFirstOnFirstChar)
137 {
138  std::string val = "abcdefg abcdefg";
139  std::string lhs;
140  std::string rhs;
141 
142  split_first(val , lhs, rhs, 'a');
143  EXPECT_EQ("abcdefg abcdefg", val);
144  EXPECT_EQ("", lhs);
145  EXPECT_EQ("bcdefg abcdefg", rhs);
146 }
147 
148 TEST(StrTest, SplitLast)
149 {
150  std::string val = "abcdefg abcdefg";
151  std::string lhs;
152  std::string rhs;
153 
154  split_last(val , lhs, rhs, 'f');
155  EXPECT_EQ("abcdefg abcdefg", val);
156  EXPECT_EQ("abcdefg abcde", lhs);
157  EXPECT_EQ("g", rhs);
158 }
159 
160 TEST(StrTest, SplitLastNoChar)
161 {
162  std::string val = "abcdefg abcdefg";
163  std::string lhs;
164  std::string rhs;
165 
166  split_last(val , lhs, rhs, 'h');
167  EXPECT_EQ("abcdefg abcdefg", val);
168  EXPECT_EQ("abcdefg abcdefg", lhs);
169  EXPECT_EQ("", rhs);
170 }
171 
172 TEST(StrTest, SplitLastOnLastChar)
173 {
174  std::string val = "abcdefg abcdefg";
175  std::string lhs;
176  std::string rhs;
177 
178  split_last(val , lhs, rhs, 'g');
179  EXPECT_EQ("abcdefg abcdefg", val);
180  EXPECT_EQ("abcdefg abcdef", lhs);
181  EXPECT_EQ("", rhs);
182 }
183 
184 
185 /*
186  * str.cc's "tokenize" function splits a string into its constituent tokens.
187  * It splits based on an input character.
188  */
189 TEST(StrTest, TokenizeOnSpace)
190 {
191  /*
192  * val has a double space between each token with trailing and leading
193  * whitespace.
194  */
195  std::string val = " Hello, this is a sentence. ";
197 
198  /*
199  * By default 'ign' is true. This means empty tokens are not included in
200  * the output list.
201  */
202  tokenize(tokens, val, ' ');
203  EXPECT_EQ(" Hello, this is a sentence. ", val);
204  EXPECT_EQ(5, tokens.size());
205  EXPECT_EQ("Hello,", tokens[0]);
206  EXPECT_EQ("this", tokens[1]);
207  EXPECT_EQ("is", tokens[2]);
208  EXPECT_EQ("a", tokens[3]);
209  EXPECT_EQ("sentence.", tokens[4]);
210 }
211 
212 TEST(StrTest, TokenizeOnSpaceIgnFalse)
213 {
214  /*
215  * val has a double space between each token with trailing and leading
216  * whitespace.
217  */
218  std::string val = " Hello, this is a sentence. ";
220 
221  tokenize(tokens, val, ' ', false);
222  EXPECT_EQ(" Hello, this is a sentence. ", val);
223  EXPECT_EQ(11, tokens.size());
224  EXPECT_EQ("", tokens[0]);
225  EXPECT_EQ("Hello,", tokens[1]);
226  EXPECT_EQ("", tokens[2]);
227  EXPECT_EQ("this", tokens[3]);
228  EXPECT_EQ("", tokens[4]);
229  EXPECT_EQ("is", tokens[5]);
230  EXPECT_EQ("", tokens[6]);
231  EXPECT_EQ("a", tokens[7]);
232  EXPECT_EQ("", tokens[8]);
233  EXPECT_EQ("sentence.", tokens[9]);
234  EXPECT_EQ("", tokens[10]);
235 }
236 
237 TEST(StrTest, TokenizedTokenDoesNotExist)
238 {
239  std::string val = "abcdefg";
241 
242  tokenize(tokens, val, 'h');
243  EXPECT_EQ("abcdefg", val);
244  EXPECT_EQ(1, tokens.size());
245  EXPECT_EQ("abcdefg", tokens[0]);
246 }
247 
248 /*
249  * str.cc's "to_number" function converts a string to a number. The function
250  * will return false if this is not possible either because the string
251  * represents a number out-of-range, or because the string cannot be parsed.
252  */
253 TEST(StrTest, ToNumber8BitInt)
254 {
255  int8_t output;
256  std::string input = "-128";
257  EXPECT_TRUE(to_number(input, output));
258  EXPECT_EQ(-128, output);
259 }
260 
261 TEST(StrTest, ToNumber8BitIntStringOutOfRange)
262 {
263  int8_t output;
264  std::string input = "-129";
265  EXPECT_FALSE(to_number(input, output));
266 }
267 
268 TEST(StrTest, ToNumber8BitIntInvalidString)
269 {
270  int8_t output;
271  std::string input = "onetwoeight";
272  EXPECT_FALSE(to_number(input, output));
273 }
274 
275 TEST(StrTest, ToNumberUnsigned8BitInt)
276 {
277  uint8_t output;
278  std::string input = "255";
279  EXPECT_TRUE(to_number(input, output));
280  EXPECT_EQ(255, output);
281 }
282 
283 TEST(StrTest, ToNumberUnsigned8BitIntNegative)
284 {
285  uint8_t output;
286  std::string input = "-1";
287  EXPECT_FALSE(to_number(input, output));
288 }
289 
291 TEST(StrTest, ToNumberUnsigned8BitIntRoundDown)
292 {
293  uint8_t output;
294  std::string input_1 = "2.99";
295  EXPECT_TRUE(to_number(input_1, output));
296  EXPECT_EQ(2, output);
297 
298  std::string input_2 = "3.99";
299  EXPECT_TRUE(to_number(input_2, output));
300  EXPECT_EQ(3, output);
301 }
302 
307 TEST(StrTest, ToNumber8BitUnsignedLimit)
308 {
309  uint8_t output;
310  std::string input = "255.99";
311  EXPECT_TRUE(to_number(input, output));
312  EXPECT_EQ(255, output);
313 }
314 
319 TEST(StrTest, ToNumber8BitUnsignedOutOfRange)
320 {
321  uint8_t output;
322  std::string input = "256.99";
323  EXPECT_FALSE(to_number(input, output));
324 }
325 
327 TEST(StrTest, ToNumberUnsignedScientific)
328 {
329  uint32_t output;
330  std::string input = "8.234e+08";
331  EXPECT_FALSE(to_number(input, output));
332 }
333 
335 TEST(StrTest, ToNumberIntScientificNegative)
336 {
337  int32_t output;
338  std::string input = "-8.234e+08";
339  EXPECT_FALSE(to_number(input, output));
340 }
341 
342 TEST(StrTest, ToNumber64BitInt)
343 {
344  int64_t output;
345  int64_t input_number = 0xFFFFFFFFFFFFFFFF;
346  std::string input = std::to_string(input_number);
347  EXPECT_TRUE(to_number(input, output));
348  EXPECT_EQ(input_number, output);
349 }
350 
351 TEST(StrTest, ToNumber64BitIntInvalidString)
352 {
353  int64_t output;
354  std::string input = " ";
355  EXPECT_FALSE(to_number(input, output));
356 }
357 
358 TEST(StrTest, ToNumberEnum)
359 {
360  enum Number
361  {
362  TWO=2,
363  };
364  Number output;
365  std::string input = "2";
366  EXPECT_TRUE(to_number(input, output));
367  EXPECT_EQ(TWO, output);
368 }
369 
371 TEST(StrTest, DISABLED_ToNumberEnumInvalid)
372 {
373  enum Number
374  {
375  TWO=2,
376  };
377  Number output;
378  std::string input = "3";
379  EXPECT_FALSE(to_number(input, output));
380 }
381 
382 TEST(StrTest, ToNumberFloat)
383 {
384  float output;
385  std::string input = "0.1";
386  float expected_output = 0.1;
387  EXPECT_TRUE(to_number(input, output));
388  EXPECT_EQ(expected_output, output);
389 }
390 
391 TEST(StrTest, ToNumberFloatIntegerString)
392 {
393  float output;
394  std::string input = "10";
395  float expected_output = 10.0;
396  EXPECT_TRUE(to_number(input, output));
397  EXPECT_EQ(expected_output, output);
398 }
399 
400 TEST(StrTest, ToNumberFloatNegative)
401 {
402  float output;
403  std::string input = "-0.1";
404  float expected_output = -0.1;
405  EXPECT_TRUE(to_number(input, output));
406  EXPECT_EQ(expected_output, output);
407 }
408 
409 TEST(StrTest, ToNumberDouble)
410 {
411  double output;
412  std::string input = "0.0001";
413  double expected_output = 0.0001;
414  EXPECT_TRUE(to_number(input, output));
415  EXPECT_EQ(expected_output, output);
416 }
417 
418 TEST(StrTest, ToNumberDoubleIntegerString)
419 {
420  double output;
421  std::string input = "12345";
422  double expected_output = 12345.0;
423  EXPECT_TRUE(to_number(input, output));
424  EXPECT_EQ(expected_output, output);
425 }
426 
427 TEST(StrTest, ToNumberDoubleNegative)
428 {
429  double output;
430  std::string input = "-1.2345";
431  double expected_output = -1.2345;
432  EXPECT_TRUE(to_number(input, output));
433  EXPECT_EQ(expected_output, output);
434 }
435 
437 TEST(StrTest, ToNumberScientific)
438 {
439  double output;
440  std::string input = "8.234e+08";
441  double expected_output = 823400000;
442  EXPECT_TRUE(to_number(input, output));
443  EXPECT_EQ(expected_output, output);
444 }
445 
446 /*
447  * The "to_bool" function takes a string, "true" or "false"
448  * (case-insenstive), and sets the second argument to the bool equivilent.
449  * The function will return false if it cannot parse the string.
450  */
451 TEST(StrTest, ToBoolTrue)
452 {
453  bool output = false;
454  EXPECT_TRUE(to_bool("TrUe", output));
455  EXPECT_TRUE(output);
456 }
457 
458 TEST(StrTest, ToBoolFalse){
459  bool output = true;
460  EXPECT_TRUE(to_bool("fAlSe", output));
461  EXPECT_FALSE(output);
462 }
463 
464 TEST(StrTest, ToBoolInvalidInput)
465 {
466  bool output;
467  EXPECT_FALSE(to_bool("falsify", output));
468 }
469 
470 /*
471  * The "quote" function take a string and returns that string quoted (i.e.,
472  * between double-quotes) if the string contains a space.
473  */
474 TEST(StrTest, QuoteStringNoSpace)
475 {
476  EXPECT_EQ("hello", quote("hello"));
477 }
478 
479 TEST(StrTest, QuoteStringWithSpace)
480 {
481  EXPECT_EQ("\"hello world\"", quote("hello world"));
482 }
483 
484 TEST(StrTest, QuoteQuotedString)
485 {
486  /*
487  * At present, a quoted string can be quoted again.
488  */
489  EXPECT_EQ("\"\"hello world\"\"", quote("\"hello world\""));
490 }
491 
492 TEST(StrTest, QuoteStringWithTab)
493 {
494  /*
495  * The "quote" function only works with standard space, not any
496  * whitepsace.
497  */
498  EXPECT_EQ("hello\tworld", quote("hello\tworld"));
499 }
500 
501 /*
502  * str.hh has three implementations of "startswith"; a function that takes
503  * string and a prefix and returns true if the string starts with the prefix.
504  * One implementation takes two strings, another takes two char*, and the
505  * third takes a string and a char* as a prefix.
506  */
507 TEST(StrTest, StartswithDoubleStringDoesStartWith)
508 {
509  std::string s = "Hello, how are you?";
510  std::string prefix = "Hello";
511  EXPECT_TRUE(startswith(s, prefix));
512 }
513 
514 TEST(StrTest, StartswithDoubleStringDoesNotStartWith)
515 {
516  std::string s = "Hello, how are you?";
517  std::string prefix = "ello";
518  EXPECT_FALSE(startswith(s, prefix));
519 }
520 
521 TEST(StrTest, StartswithDoubleCharArrayDoesStartWith)
522 {
523  const char* s = "abcdefg";
524  const char* prefix = "ab";
525  EXPECT_TRUE(startswith(s, prefix));
526 }
527 
528 TEST(StrTest, StartswithDoubleCharArrayDoesNotStartWith)
529 {
530  const char* s = " abcdefg";
531  const char* prefix = "a";
532  EXPECT_FALSE(startswith(s, prefix));
533 }
534 
535 TEST(StrTest, StartswithStringCharArrayDoesStartWith)
536 {
537  std::string s = "foobarr";
538  const char* prefix = "f";
539  EXPECT_TRUE(startswith(s, prefix));
540 }
541 
542 TEST(StrTest, StartswithStringCharArrayDoesNotStartWith)
543 {
544  std::string s = "foobarr";
545  const char* prefix = "barr";
546  EXPECT_FALSE(startswith(s, prefix));
547 }
Bitfield< 1 > s
Definition: pagetable.hh:64
Bitfield< 63 > val
Definition: misc.hh:776
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::string to_lower(const std::string &s)
Definition: str.hh:74
bool to_number(const std::string &value, Pixel &retval)
Definition: pixel.hh:217
bool startswith(const char *s, const char *prefix)
Return true if 's' starts with the prefix string 'prefix'.
Definition: str.hh:229
bool to_bool(const std::string &value, bool &retval)
Turn a string representation of a boolean into a boolean value.
Definition: str.hh:191
std::string quote(const std::string &s)
Definition: str.hh:208
void tokenize(std::vector< std::string > &v, const std::string &s, char token, bool ignore)
Definition: str.cc:68
bool split_last(const std::string &s, std::string &lhs, std::string &rhs, char c)
Definition: str.cc:53
static void output(const char *filename)
Definition: debug.cc:60
void eat_end_white(std::string &s)
Definition: str.hh:59
void eat_white(std::string &s)
Definition: str.hh:67
void eat_lead_white(std::string &s)
Definition: str.hh:49
bool split_first(const std::string &s, std::string &lhs, std::string &rhs, char c)
Definition: str.cc:38
const std::string to_string(sc_enc enc)
Definition: sc_fxdefs.cc:60
TEST(StrTest, EatLeadWhite)
Definition: str.test.cc:51

Generated on Wed Dec 21 2022 10:22:29 for gem5 by doxygen 1.9.1