1// Copyright 2005 The RE2 Authors. All Rights Reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// This tests to make sure numbers are parsed from strings 6// correctly. 7// Todo: Expand the test to validate strings parsed to the other types 8// supported by RE2::Arg class 9 10#include "util/test.h" 11#include "re2/re2.h" 12 13namespace re2 { 14 15struct SuccessTable { 16 const char * value_string; 17 int64 value; 18 bool success[6]; 19}; 20 21// Test boundary cases for different integral sizes. 22// Specifically I want to make sure that values outside the boundries 23// of an integral type will fail and that negative numbers will fail 24// for unsigned types. The following table contains the boundaries for 25// the various integral types and has entries for whether or not each 26// type can contain the given value. 27const SuccessTable kSuccessTable[] = { 28// string integer value short ushort int uint int64 uint64 29// 0 to 2^7-1 30{ "0", 0, { true, true, true, true, true, true }}, 31{ "127", 127, { true, true, true, true, true, true }}, 32 33// -1 to -2^7 34{ "-1", -1, { true, false, true, false, true, false }}, 35{ "-128", -128, { true, false, true, false, true, false }}, 36 37// 2^7 to 2^8-1 38{ "128", 128, { true, true, true, true, true, true }}, 39{ "255", 255, { true, true, true, true, true, true }}, 40 41// 2^8 to 2^15-1 42{ "256", 256, { true, true, true, true, true, true }}, 43{ "32767", 32767, { true, true, true, true, true, true }}, 44 45// -2^7-1 to -2^15 46{ "-129", -129, { true, false, true, false, true, false }}, 47{ "-32768", -32768, { true, false, true, false, true, false }}, 48 49// 2^15 to 2^16-1 50{ "32768", 32768, { false, true, true, true, true, true }}, 51{ "65535", 65535, { false, true, true, true, true, true }}, 52 53// 2^16 to 2^31-1 54{ "65536", 65536, { false, false, true, true, true, true }}, 55{ "2147483647", 2147483647, { false, false, true, true, true, true }}, 56 57// -2^15-1 to -2^31 58{ "-32769", -32769, { false, false, true, false, true, false }}, 59{ "-2147483648", 60 static_cast<int64>(0xFFFFFFFF80000000LL), 61{ false, false, true, false, true, false }}, 62 63// 2^31 to 2^32-1 64{ "2147483648", 2147483648U, { false, false, false, true, true, true }}, 65{ "4294967295", 4294967295U, { false, false, false, true, true, true }}, 66 67// 2^32 to 2^63-1 68{ "4294967296", 4294967296LL, { false, false, false, false, true, true }}, 69{ "9223372036854775807", 70 9223372036854775807LL, { false, false, false, false, true, true }}, 71 72// -2^31-1 to -2^63 73{ "-2147483649", -2147483649LL, { false, false, false, false, true, false }}, 74{ "-9223372036854775808", static_cast<int64>(0x8000000000000000LL), 75 { false, false, false, false, true, false }}, 76 77// 2^63 to 2^64-1 78{ "9223372036854775808", static_cast<int64>(9223372036854775808ULL), 79 { false, false, false, false, false, true }}, 80{ "18446744073709551615", static_cast<int64>(18446744073709551615ULL), 81 { false, false, false, false, false, true }}, 82 83// >= 2^64 84{ "18446744073709551616", 0, { false, false, false, false, false, false }}, 85}; 86 87const int kNumStrings = ARRAYSIZE(kSuccessTable); 88 89// It's ugly to use a macro, but we apparently can't use the ASSERT_TRUE_M 90// macro outside of a TEST block and this seems to be the only way to 91// avoid code duplication. I can also pull off a couple nice tricks 92// using concatenation for the type I'm checking against. 93#define PARSE_FOR_TYPE(type, column) { \ 94 type r; \ 95 for ( int i = 0; i < kNumStrings; ++i ) { \ 96 RE2::Arg arg(&r); \ 97 const char* const p = kSuccessTable[i].value_string; \ 98 bool retval = arg.Parse(p, strlen(p)); \ 99 bool success = kSuccessTable[i].success[column]; \ 100 ASSERT_TRUE_M(retval == success, \ 101 StringPrintf("Parsing '%s' for type " #type " should return %d", \ 102 p, success).c_str()); \ 103 if ( success ) { \ 104 ASSERT_EQUALS(r, kSuccessTable[i].value); \ 105 } \ 106 } \ 107} 108 109TEST(REArgTest, Int16Test) { 110 PARSE_FOR_TYPE(int16, 0); 111} 112 113TEST(REArgTest, Uint16Test) { 114 PARSE_FOR_TYPE(uint16, 1); 115} 116 117TEST(REArgTest, IntTest) { 118 PARSE_FOR_TYPE(int, 2); 119} 120 121TEST(REArgTest, UInt32Test) { 122 PARSE_FOR_TYPE(uint32, 3); 123} 124 125TEST(REArgTest, Iint64Test) { 126 PARSE_FOR_TYPE(int64, 4); 127} 128 129TEST(REArgTest, Uint64Test) { 130 PARSE_FOR_TYPE(uint64, 5); 131} 132 133} // namespace re2 134