1 | // Copyright 2006 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 | // Test parse.cc, dump.cc, and tostring.cc. |
6 | |
7 | #include <stddef.h> |
8 | #include <map> |
9 | #include <string> |
10 | #include <vector> |
11 | |
12 | #include "util/test.h" |
13 | #include "util/logging.h" |
14 | #include "re2/regexp.h" |
15 | |
16 | namespace re2 { |
17 | |
18 | // Test that overflowed ref counts work. |
19 | TEST(Regexp, BigRef) { |
20 | Regexp* re; |
21 | re = Regexp::Parse("x" , Regexp::NoParseFlags, NULL); |
22 | for (int i = 0; i < 100000; i++) |
23 | re->Incref(); |
24 | for (int i = 0; i < 100000; i++) |
25 | re->Decref(); |
26 | ASSERT_EQ(re->Ref(), 1); |
27 | re->Decref(); |
28 | } |
29 | |
30 | // Test that very large Concats work. |
31 | // Depends on overflowed ref counts working. |
32 | TEST(Regexp, BigConcat) { |
33 | Regexp* x; |
34 | x = Regexp::Parse("x" , Regexp::NoParseFlags, NULL); |
35 | std::vector<Regexp*> v(90000, x); // ToString bails out at 100000 |
36 | for (size_t i = 0; i < v.size(); i++) |
37 | x->Incref(); |
38 | ASSERT_EQ(x->Ref(), 1 + static_cast<int>(v.size())) << x->Ref(); |
39 | Regexp* re = Regexp::Concat(v.data(), static_cast<int>(v.size()), |
40 | Regexp::NoParseFlags); |
41 | ASSERT_EQ(re->ToString(), std::string(v.size(), 'x')); |
42 | re->Decref(); |
43 | ASSERT_EQ(x->Ref(), 1) << x->Ref(); |
44 | x->Decref(); |
45 | } |
46 | |
47 | TEST(Regexp, NamedCaptures) { |
48 | Regexp* x; |
49 | RegexpStatus status; |
50 | x = Regexp::Parse( |
51 | "(?P<g1>a+)|(e)(?P<g2>w*)+(?P<g1>b+)" , Regexp::PerlX, &status); |
52 | EXPECT_TRUE(status.ok()); |
53 | EXPECT_EQ(4, x->NumCaptures()); |
54 | const std::map<std::string, int>* have = x->NamedCaptures(); |
55 | EXPECT_TRUE(have != NULL); |
56 | EXPECT_EQ(2, have->size()); // there are only two named groups in |
57 | // the regexp: 'g1' and 'g2'. |
58 | std::map<std::string, int> want; |
59 | want["g1" ] = 1; |
60 | want["g2" ] = 3; |
61 | EXPECT_EQ(want, *have); |
62 | x->Decref(); |
63 | delete have; |
64 | } |
65 | |
66 | TEST(Regexp, CaptureNames) { |
67 | Regexp* x; |
68 | RegexpStatus status; |
69 | x = Regexp::Parse( |
70 | "(?P<g1>a+)|(e)(?P<g2>w*)+(?P<g1>b+)" , Regexp::PerlX, &status); |
71 | EXPECT_TRUE(status.ok()); |
72 | EXPECT_EQ(4, x->NumCaptures()); |
73 | const std::map<int, std::string>* have = x->CaptureNames(); |
74 | EXPECT_TRUE(have != NULL); |
75 | EXPECT_EQ(3, have->size()); |
76 | std::map<int, std::string> want; |
77 | want[1] = "g1" ; |
78 | want[3] = "g2" ; |
79 | want[4] = "g1" ; |
80 | |
81 | EXPECT_EQ(want, *have); |
82 | x->Decref(); |
83 | delete have; |
84 | } |
85 | |
86 | } // namespace re2 |
87 | |