15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2009 The RE2 Authors.  All Rights Reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// license that can be found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/test.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "re2/regexp.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace re2 {
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PrefixTest {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* regexp;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool return_value;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* prefix;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool foldcase;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* suffix;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PrefixTest tests[] = {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the regexp is missing a ^, there's no required prefix.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "abc", false },
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "", false },
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "(?m)^", false },
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the regexp immediately goes into
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // something not a literal match, there's no required prefix.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "^(abc)", false },
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "^a*",  false },
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Otherwise, it should work.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "^abc$", true, "abc", false, "(?-m:$)" },
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "^abc", "true", "abc", false, "" },
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "^(?i)abc", true, "abc", true, "" },
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "^abcd*", true, "abc", false, "d*" },
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "^[Aa][Bb]cd*", true, "ab", true, "cd*" },
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "^ab[Cc]d*", true, "ab", false, "[Cc]d*" },
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "^☺abc", true, "☺abc", false, "" },
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RequiredPrefix, SimpleTests) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < arraysize(tests); i++) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PrefixTest& t = tests[i];
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int j = 0; j < 2; j++) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Regexp::ParseFlags flags = Regexp::LikePerl;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (j == 0)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        flags = flags | Regexp::Latin1;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Regexp* re = Regexp::Parse(t.regexp, flags, NULL);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(re) << " " << t.regexp;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      string p;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool f = false;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Regexp* s = NULL;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK_EQ(t.return_value, re->RequiredPrefix(&p, &f, &s))
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << " " << t.regexp << " " << (j==0 ? "latin1" : "utf") << " " << re->Dump();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (t.return_value) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CHECK_EQ(p, string(t.prefix))
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << " " << t.regexp << " " << (j==0 ? "latin1" : "utf");
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CHECK_EQ(f, t.foldcase)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << " " << t.regexp << " " << (j==0 ? "latin1" : "utf");
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CHECK_EQ(s->ToString(), string(t.suffix))
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << " " << t.regexp << " " << (j==0 ? "latin1" : "utf");
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        s->Decref();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      re->Decref();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace re2
68