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
16namespace re2 {
17
18// Test that overflowed ref counts work.
19TEST(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.
32TEST(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
47TEST(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
66TEST(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