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