1 // Copyright 2009 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 #include "util/test.h"
6 #include "re2/regexp.h"
7 
8 namespace re2 {
9 
10 struct PrefixTest {
11   const char* regexp;
12   bool return_value;
13   const char* prefix;
14   bool foldcase;
15   const char* suffix;
16 };
17 
18 static PrefixTest tests[] = {
19   // If the regexp is missing a ^, there's no required prefix.
20   { "abc", false },
21   { "", false },
22   { "(?m)^", false },
23 
24   // If the regexp immediately goes into
25   // something not a literal match, there's no required prefix.
26   { "^(abc)", false },
27   { "^a*",  false },
28 
29   // Otherwise, it should work.
30   { "^abc$", true, "abc", false, "(?-m:$)" },
31   { "^abc", "true", "abc", false, "" },
32   { "^(?i)abc", true, "abc", true, "" },
33   { "^abcd*", true, "abc", false, "d*" },
34   { "^[Aa][Bb]cd*", true, "ab", true, "cd*" },
35   { "^ab[Cc]d*", true, "ab", false, "[Cc]d*" },
36   { "^☺abc", true, "☺abc", false, "" },
37 };
38 
TEST(RequiredPrefix,SimpleTests)39 TEST(RequiredPrefix, SimpleTests) {
40   for (int i = 0; i < arraysize(tests); i++) {
41     const PrefixTest& t = tests[i];
42     for (int j = 0; j < 2; j++) {
43       Regexp::ParseFlags flags = Regexp::LikePerl;
44       if (j == 0)
45         flags = flags | Regexp::Latin1;
46       Regexp* re = Regexp::Parse(t.regexp, flags, NULL);
47       CHECK(re) << " " << t.regexp;
48       string p;
49       bool f = false;
50       Regexp* s = NULL;
51       CHECK_EQ(t.return_value, re->RequiredPrefix(&p, &f, &s))
52         << " " << t.regexp << " " << (j==0 ? "latin1" : "utf") << " " << re->Dump();
53       if (t.return_value) {
54         CHECK_EQ(p, string(t.prefix))
55           << " " << t.regexp << " " << (j==0 ? "latin1" : "utf");
56         CHECK_EQ(f, t.foldcase)
57           << " " << t.regexp << " " << (j==0 ? "latin1" : "utf");
58         CHECK_EQ(s->ToString(), string(t.suffix))
59           << " " << t.regexp << " " << (j==0 ? "latin1" : "utf");
60         s->Decref();
61       }
62       re->Decref();
63     }
64   }
65 }
66 
67 }  // namespace re2
68