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