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
8namespace re2 {
9
10struct PrefixTest {
11  const char* regexp;
12  bool return_value;
13  const char* prefix;
14  bool foldcase;
15  const char* suffix;
16};
17
18static 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
39TEST(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