10d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin// Copyright 2009 The RE2 Authors.  All Rights Reserved.
20d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin// Use of this source code is governed by a BSD-style
30d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin// license that can be found in the LICENSE file.
40d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
50d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#include "util/test.h"
60d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#include "re2/regexp.h"
70d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
80d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinnamespace re2 {
90d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
100d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinstruct PrefixTest {
110d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  const char* regexp;
120d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  bool return_value;
130d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  const char* prefix;
140d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  bool foldcase;
150d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  const char* suffix;
160d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin};
170d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
180d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinstatic PrefixTest tests[] = {
190d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  // If the regexp is missing a ^, there's no required prefix.
200d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "abc", false },
210d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "", false },
220d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "(?m)^", false },
230d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
240d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  // If the regexp immediately goes into
250d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  // something not a literal match, there's no required prefix.
260d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "^(abc)", false },
270d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "^a*",  false },
280d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
290d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  // Otherwise, it should work.
300d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "^abc$", true, "abc", false, "(?-m:$)" },
310d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "^abc", "true", "abc", false, "" },
320d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "^(?i)abc", true, "abc", true, "" },
330d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "^abcd*", true, "abc", false, "d*" },
340d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "^[Aa][Bb]cd*", true, "ab", true, "cd*" },
350d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "^ab[Cc]d*", true, "ab", false, "[Cc]d*" },
360d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  { "^☺abc", true, "☺abc", false, "" },
370d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin};
380d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
390d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander GutkinTEST(RequiredPrefix, SimpleTests) {
400d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  for (int i = 0; i < arraysize(tests); i++) {
410d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin    const PrefixTest& t = tests[i];
420d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin    for (int j = 0; j < 2; j++) {
430d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      Regexp::ParseFlags flags = Regexp::LikePerl;
440d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      if (j == 0)
450d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin        flags = flags | Regexp::Latin1;
460d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      Regexp* re = Regexp::Parse(t.regexp, flags, NULL);
470d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      CHECK(re) << " " << t.regexp;
480d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      string p;
490d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      bool f = false;
500d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      Regexp* s = NULL;
510d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      CHECK_EQ(t.return_value, re->RequiredPrefix(&p, &f, &s))
520d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin        << " " << t.regexp << " " << (j==0 ? "latin1" : "utf") << " " << re->Dump();
530d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      if (t.return_value) {
540d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin        CHECK_EQ(p, string(t.prefix))
550d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin          << " " << t.regexp << " " << (j==0 ? "latin1" : "utf");
560d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin        CHECK_EQ(f, t.foldcase)
570d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin          << " " << t.regexp << " " << (j==0 ? "latin1" : "utf");
580d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin        CHECK_EQ(s->ToString(), string(t.suffix))
590d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin          << " " << t.regexp << " " << (j==0 ? "latin1" : "utf");
600d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin        s->Decref();
610d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      }
620d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      re->Decref();
630d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin    }
640d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  }
650d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin}
660d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
670d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin}  // namespace re2
68