15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -*- coding: utf-8 -*-
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2002-2009 The RE2 Authors.  All Rights Reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// license that can be found in the LICENSE file.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO: Test extractions for PartialMatch/Consume
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef WIN32
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/mman.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/test.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "re2/re2.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "re2/regexp.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define snprintf _snprintf
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DECLARE_bool(logtostderr);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace re2 {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, HexTests) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "hex tests";
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_HEX(type, value) \
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do { \
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    type v; \
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch(#value, "([0-9a-fA-F]+)[uUlL]*", RE2::Hex(&v))); \
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, 0x ## value); \
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("0x" #value, "([0-9a-fA-FxX]+)[uUlL]*", RE2::CRadix(&v))); \
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, 0x ## value); \
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while(0)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_HEX(short,              2bad);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_HEX(unsigned short,     2badU);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_HEX(int,                dead);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_HEX(unsigned int,       deadU);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_HEX(long,               7eadbeefL);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_HEX(unsigned long,      deadbeefUL);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_HEX(long long,          12345678deadbeefLL);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_HEX(unsigned long long, cafebabedeadbeefULL);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef CHECK_HEX
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, OctalTests) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "octal tests";
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_OCTAL(type, value) \
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do { \
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    type v; \
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch(#value, "([0-7]+)[uUlL]*", RE2::Octal(&v))); \
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, 0 ## value); \
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("0" #value, "([0-9a-fA-FxX]+)[uUlL]*", RE2::CRadix(&v))); \
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, 0 ## value); \
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while(0)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_OCTAL(short,              77777);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_OCTAL(unsigned short,     177777U);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_OCTAL(int,                17777777777);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_OCTAL(unsigned int,       37777777777U);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_OCTAL(long,               17777777777L);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_OCTAL(unsigned long,      37777777777UL);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_OCTAL(long long,          777777777777777777777LL);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_OCTAL(unsigned long long, 1777777777777777777777ULL);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef CHECK_OCTAL
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, DecimalTests) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "decimal tests";
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_DECIMAL(type, value) \
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do { \
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    type v; \
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch(#value, "(-?[0-9]+)[uUlL]*", &v)); \
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, value); \
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch(#value, "(-?[0-9a-fA-FxX]+)[uUlL]*", RE2::CRadix(&v))); \
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, value); \
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while(0)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_DECIMAL(short,              -1);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_DECIMAL(unsigned short,     9999);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_DECIMAL(int,                -1000);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_DECIMAL(unsigned int,       12345U);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_DECIMAL(long,               -10000000L);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_DECIMAL(unsigned long,      3083324652U);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_DECIMAL(long long,          -100000000000000LL);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_DECIMAL(unsigned long long, 1234567890987654321ULL);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef CHECK_DECIMAL
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, Replace) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "TestReplace";
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ReplaceTest {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *regexp;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *rewrite;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *original;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *single;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *global;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int        greplace_count;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const ReplaceTest tests[] = {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "(qu|[b-df-hj-np-tv-z]*)([a-z]+)",
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\\2\\1ay",
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "the quick brown fox jumps over the lazy dogs.",
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ethay quick brown fox jumps over the lazy dogs.",
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ethay ickquay ownbray oxfay umpsjay overay ethay azylay ogsday.",
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      9 },
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "\\w+",
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\\0-NOSPAM",
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "abcd.efghi@google.com",
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "abcd-NOSPAM.efghi@google.com",
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "abcd-NOSPAM.efghi-NOSPAM@google-NOSPAM.com-NOSPAM",
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      4 },
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "^",
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(START)",
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foo",
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(START)foo",
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(START)foo",
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1 },
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "^",
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(START)",
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(START)",
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(START)",
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1 },
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "$",
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(END)",
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(END)",
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(END)",
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1 },
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "b",
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bb",
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ababababab",
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "abbabababab",
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "abbabbabbabbabb",
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      5 },
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "b",
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bb",
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bbbbbb",
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bbbbbbb",
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bbbbbbbbbbbb",
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      6 },
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "b+",
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bb",
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bbbbbb",
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bb",
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bb",
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1 },
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "b*",
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bb",
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bbbbbb",
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bb",
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bb",
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1 },
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "b*",
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bb",
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "aaaaa",
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bbaaaaa",
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "bbabbabbabbabbabb",
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      6 },
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check newline handling
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "a.*a",
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(\\0)",
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "aba\naba",
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(aba)\naba",
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "(aba)\n(aba)",
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      2 },
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "", NULL, NULL, NULL, NULL, 0 }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (const ReplaceTest *t = tests; t->original != NULL; ++t) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG(1) << StringPrintf("\"%s\" =~ s/%s/%s/g", t->original, t->regexp, t->rewrite);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string one(t->original);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::Replace(&one, t->regexp, t->rewrite));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(one, t->single);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string all(t->original);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(RE2::GlobalReplace(&all, t->regexp, t->rewrite), t->greplace_count)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Got: " << all;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(all, t->global);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestCheckRewriteString(const char* regexp, const char* rewrite,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool expect_ok) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string error;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 exp(regexp);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool actual_ok = exp.CheckRewriteString(rewrite, &error);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expect_ok, actual_ok) << " for " << rewrite << " error: " << error;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CheckRewriteString, all) {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCheckRewriteString("abc", "foo", true);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCheckRewriteString("abc", "foo\\", false);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCheckRewriteString("abc", "foo\\0bar", true);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCheckRewriteString("a(b)c", "foo", true);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCheckRewriteString("a(b)c", "foo\\0bar", true);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCheckRewriteString("a(b)c", "foo\\1bar", true);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCheckRewriteString("a(b)c", "foo\\2bar", false);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCheckRewriteString("a(b)c", "f\\\\2o\\1o", true);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCheckRewriteString("a(b)(c)", "foo\\12", true);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCheckRewriteString("a(b)(c)", "f\\2o\\1o", true);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCheckRewriteString("a(b)(c)", "f\\oo\\1", false);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, Extract) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "TestExtract";
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string s;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::Extract("boris@kremvax.ru", "(.*)@([^.]*)", "\\2!\\1", &s));
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(s, "kremvax!boris");
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::Extract("foo", ".*", "'\\0'", &s));
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(s, "'foo'");
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // check that false match doesn't overwrite
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::Extract("baz", "bar", "'\\0'", &s));
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(s, "'foo'");
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, Consume) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "TestConsume";
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 r("\\s*(\\w+)");    // matches a word, possibly proceeded by whitespace
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string word;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string s("   aaa b!@#$@#$cccc");
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece input(s);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::Consume(&input, r, &word));
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word, "aaa") << " input: " << input;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::Consume(&input, r, &word));
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word, "b") << " input: " << input;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(! RE2::Consume(&input, r, &word)) << " input: " << input;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, ConsumeN) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const string s(" one two three 4");
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece input(s);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2::Arg argv[2];
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const RE2::Arg* const args[2] = { &argv[0], &argv[1] };
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 0 arg
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::ConsumeN(&input, "\\s*(\\w+)", args, 0));  // Skips "one".
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1 arg
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string word;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  argv[0] = &word;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::ConsumeN(&input, "\\s*(\\w+)", args, 1));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("two", word);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Multi-args
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int n;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  argv[1] = &n;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::ConsumeN(&input, "\\s*(\\w+)\\s*(\\d+)", args, 2));
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("three", word);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, n);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FindAndConsume) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "TestFindAndConsume";
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 r("(\\w+)");      // matches a word
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string word;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string s("   aaa b!@#$@#$cccc");
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece input(s);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FindAndConsume(&input, r, &word));
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word, "aaa");
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FindAndConsume(&input, r, &word));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word, "b");
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FindAndConsume(&input, r, &word));
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word, "cccc");
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(! RE2::FindAndConsume(&input, r, &word));
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that FindAndConsume works without any submatches.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Earlier version used uninitialized data for
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // length to consume.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  input = "aaa";
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FindAndConsume(&input, "aaa"));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(input, "");
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FindAndConsumeN) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const string s(" one two three 4");
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece input(s);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2::Arg argv[2];
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const RE2::Arg* const args[2] = { &argv[0], &argv[1] };
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 0 arg
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FindAndConsumeN(&input, "(\\w+)", args, 0));  // Skips "one".
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1 arg
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string word;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  argv[0] = &word;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FindAndConsumeN(&input, "(\\w+)", args, 1));
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("two", word);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Multi-args
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int n;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  argv[1] = &n;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FindAndConsumeN(&input, "(\\w+)\\s*(\\d+)", args, 2));
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("three", word);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, n);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, MatchNumberPeculiarity) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "TestMatchNumberPeculiarity";
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 r("(foo)|(bar)|(baz)");
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string word1;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string word2;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string word3;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch("foo", r, &word1, &word2, &word3));
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word1, "foo");
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word2, "");
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word3, "");
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch("bar", r, &word1, &word2, &word3));
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word1, "");
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word2, "bar");
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word3, "");
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch("baz", r, &word1, &word2, &word3));
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word1, "");
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word2, "");
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(word3, "baz");
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::PartialMatch("f", r, &word1, &word2, &word3));
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string a;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("hello", "(foo)|hello", &a));
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a, "");
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, Match) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re("((\\w+):([0-9]+))");   // extracts host and port
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece group[4];
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No match.
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece s = "zyzzyva";
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!re.Match(s, 0, s.size(), RE2::UNANCHORED,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  group, arraysize(group)));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Matches and extracts.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  s = "a chrisr:9000 here";
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(re.Match(s, 0, s.size(), RE2::UNANCHORED,
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 group, arraysize(group)));
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(group[0], "chrisr:9000");
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(group[1], "chrisr:9000");
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(group[2], "chrisr");
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(group[3], "9000");
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string all, host;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int port;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch("a chrisr:9000 here", re, &all, &host, &port));
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(all, "chrisr:9000");
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(host, "chrisr");
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(port, 9000);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestRecursion(int size, const char *pattern) {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fill up a string repeating the pattern given
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string domain;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  domain.resize(size);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int patlen = strlen(pattern);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < size; ++i) {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    domain[i] = pattern[i % patlen];
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just make sure it doesn't crash due to too much recursion.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re("([a-zA-Z0-9]|-)+(\\.([a-zA-Z0-9]|-)+)*(\\.)?", RE2::Quiet);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2::FullMatch(domain, re);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A meta-quoted string, interpreted as a pattern, should always match
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the original unquoted string.
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TestQuoteMeta(string unquoted,
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const RE2::Options& options = RE2::DefaultOptions) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string quoted = RE2::QuoteMeta(unquoted);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re(quoted, options);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE_M(RE2::FullMatch(unquoted, re),
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Unquoted='" + unquoted + "', quoted='" + quoted + "'.");
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A meta-quoted string, interpreted as a pattern, should always match
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the original unquoted string.
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void NegativeTestQuoteMeta(string unquoted, string should_not_match,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const RE2::Options& options = RE2::DefaultOptions) {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string quoted = RE2::QuoteMeta(unquoted);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re(quoted, options);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE_M(RE2::FullMatch(should_not_match, re),
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 "Unquoted='" + unquoted + "', quoted='" + quoted + "'.");
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that quoted meta characters match their original strings,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and that a few things that shouldn't match indeed do not.
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuoteMeta, Simple) {
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("foo");
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("foo.bar");
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("foo\\.bar");
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("[1-9]");
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("1.5-2.0?");
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("\\d");
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("Who doesn't like ice cream?");
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("((a|b)c?d*e+[f-h]i)");
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("((?!)xxx).*yyy");
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("([");
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuoteMeta, SimpleNegative) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("foo", "bar");
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("...", "bar");
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("\\.", ".");
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("\\.", "..");
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("(a)", "a");
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("(a|b)", "a");
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("(a|b)", "(a)");
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("(a|b)", "a|b");
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("[0-9]", "0");
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("[0-9]", "0-9");
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("[0-9]", "[9]");
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("((?!)xxx)", "xxx");
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuoteMeta, Latin1) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("3\xb2 = 9", RE2::Latin1);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuoteMeta, UTF8) {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("Plácido Domingo");
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("xyz");  // No fancy utf8.
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("\xc2\xb0");  // 2-byte utf8 -- a degree symbol.
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("27\xc2\xb0 degrees");  // As a middle character.
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("\xe2\x80\xb3");  // 3-byte utf8 -- a double prime.
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("\xf0\x9d\x85\x9f");  // 4-byte utf8 -- a music note.
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta("27\xc2\xb0");  // Interpreted as Latin-1, this should
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                // still work.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta("27\xc2\xb0",
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        "27\\\xc2\\\xb0");  // 2-byte utf8 -- a degree symbol.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuoteMeta, HasNull) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string has_null;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // string with one null character
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_null += '\0';
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta(has_null);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta(has_null, "");
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't want null-followed-by-'1' to be interpreted as '\01'.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_null += '1';
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestQuoteMeta(has_null);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NegativeTestQuoteMeta(has_null, "\1");
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ProgramSize, BigProgram) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re_simple("simple regexp");
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re_medium("medium.*regexp");
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re_complex("hard.{1,128}regexp");
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GT(re_simple.ProgramSize(), 0);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GT(re_medium.ProgramSize(), re_simple.ProgramSize());
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GT(re_complex.ProgramSize(), re_medium.ProgramSize());
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Issue 956519: handling empty character sets was
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// causing NULL dereference.  This tests a few empty character sets.
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (The way to get an empty character set is to negate a full one.)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(EmptyCharset, Fuzz) {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char *empties[] = {
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "[^\\S\\s]",
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "[^\\S[:space:]]",
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "[^\\D\\d]",
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "[^\\D[:digit:]]"
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < arraysize(empties); i++)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2(empties[i]).Match("abc", 0, 3, RE2::UNANCHORED, NULL, 0));
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that named groups work correctly.
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(Capture, NamedGroups) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re("(hello world)");
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(re.NumberOfCapturingGroups(), 1);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const map<string, int>& m = re.NamedCapturingGroups();
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(m.size(), 0);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re("(?P<A>expr(?P<B>expr)(?P<C>expr))((expr)(?P<D>expr))");
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(re.NumberOfCapturingGroups(), 6);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const map<string, int>& m = re.NamedCapturingGroups();
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(m.size(), 4);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(m.find("A")->second, 1);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(m.find("B")->second, 2);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(m.find("C")->second, 3);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(m.find("D")->second, 6);  // $4 and $5 are anonymous
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchWithNoArgs) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("h", "h"));
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("hello", "hello"));
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("hello", "h.*o"));
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("othello", "h.*o"));       // Must be anchored at front
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("hello!", "h.*o"));        // Must be anchored at end
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, PartialMatch) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch("x", "x"));
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch("hello", "h.*o"));
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch("othello", "h.*o"));
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch("hello!", "h.*o"));
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch("x", "((((((((((((((((((((x))))))))))))))))))))"));
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, PartialMatchN) {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2::Arg argv[2];
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const RE2::Arg* const args[2] = { &argv[0], &argv[1] };
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 0 arg
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatchN("hello", "e.*o", args, 0));
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::PartialMatchN("othello", "a.*o", args, 0));
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1 arg
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  argv[0] = &i;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatchN("1001 nights", "(\\d+)", args, 1));
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1001, i);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::PartialMatchN("three", "(\\d+)", args, 1));
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Multi-arg
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string s;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  argv[1] = &s;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatchN("answer: 42:life", "(\\d+):(\\w+)", args, 2));
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(42, i);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("life", s);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::PartialMatchN("hi1", "(\\w+)(1)", args, 2));
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchZeroArg) {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Zero-arg
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("1001", "\\d+"));
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchOneArg) {
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Single-arg
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("1001", "(\\d+)",   &i));
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(i, 1001);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("-123", "(-?\\d+)", &i));
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(i, -123);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("10", "()\\d+", &i));
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("1234567890123456789012345678901234567890",
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       "(\\d+)", &i));
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchIntegerArg) {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Digits surrounding integer-arg
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("1234", "1(\\d*)4", &i));
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(i, 23);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("1234", "(\\d)\\d+", &i));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(i, 1);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("-1234", "(-\\d)\\d+", &i));
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(i, -1);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch("1234", "(\\d)", &i));
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(i, 1);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch("-1234", "(-\\d)", &i));
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(i, -1);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchStringArg) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string s;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // String-arg
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("hello", "h(.*)o", &s));
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(s, string("ell"));
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchStringPieceArg) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StringPiece-arg
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece sp;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("ruby:1234", "(\\w+):(\\d+)", &sp, &i));
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(sp.size(), 4);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(memcmp(sp.data(), "ruby", 4) == 0);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(i, 1234);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchMultiArg) {
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string s;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Multi-arg
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("ruby:1234", "(\\w+):(\\d+)", &s, &i));
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(s, string("ruby"));
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(i, 1234);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchN) {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2::Arg argv[2];
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const RE2::Arg* const args[2] = { &argv[0], &argv[1] };
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 0 arg
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatchN("hello", "h.*o", args, 0));
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatchN("othello", "h.*o", args, 0));
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1 arg
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  argv[0] = &i;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatchN("1001", "(\\d+)", args, 1));
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1001, i);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatchN("three", "(\\d+)", args, 1));
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Multi-arg
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string s;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  argv[1] = &s;
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatchN("42:life", "(\\d+):(\\w+)", args, 2));
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(42, i);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("life", s);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatchN("hi1", "(\\w+)(1)", args, 2));
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchIgnoredArg) {
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string s;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ignored arg
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("ruby:1234", "(\\w+)(:)(\\d+)", &s, (void*)NULL, &i));
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(s, string("ruby"));
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(i, 1234);
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchTypedNullArg) {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string s;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ignore non-void* NULL arg
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("hello", "he(.*)lo", (char*)NULL));
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("hello", "h(.*)o", (string*)NULL));
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("hello", "h(.*)o", (StringPiece*)NULL));
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("1234", "(.*)", (int*)NULL));
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("1234567890123456", "(.*)", (long long*)NULL));
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("123.4567890123456", "(.*)", (double*)NULL));
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("123.4567890123456", "(.*)", (float*)NULL));
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fail on non-void* NULL arg if the match doesn't parse for the given type.
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("hello", "h(.*)lo", &s, (char*)NULL));
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("hello", "(.*)", (int*)NULL));
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("1234567890123456", "(.*)", (int*)NULL));
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("hello", "(.*)", (double*)NULL));
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("hello", "(.*)", (float*)NULL));
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef WIN32
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that numeric parsing code does not read past the end of
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the number being parsed.
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, NULTerminated) {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *v;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x;
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  long pagesize = sysconf(_SC_PAGE_SIZE);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MAP_ANONYMOUS
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAP_ANONYMOUS MAP_ANON
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v = static_cast<char*>(mmap(NULL, 2*pagesize, PROT_READ|PROT_WRITE,
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              MAP_ANONYMOUS|MAP_PRIVATE, -1, 0));
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(v != reinterpret_cast<char*>(-1));
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Memory at " << (void*)v;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(munmap(v + pagesize, pagesize), 0) << " error " << errno;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v[pagesize - 1] = '1';
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  x = 0;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch(StringPiece(v + pagesize - 1, 1), "(.*)", &x));
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(x, 1);
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchTypeTests) {
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Type tests
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string zeros(100, '0');
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char c;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("Hello", "(H)ello", &c));
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(c, 'H');
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char c;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("Hello", "(H)ello", &c));
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(c, static_cast<unsigned char>('H'));
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int16 v;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("100",     "(-?\\d+)", &v));    CHECK_EQ(v, 100);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("-100",    "(-?\\d+)", &v));    CHECK_EQ(v, -100);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("32767",   "(-?\\d+)", &v));    CHECK_EQ(v, 32767);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("-32768",  "(-?\\d+)", &v));    CHECK_EQ(v, -32768);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch("-32769", "(-?\\d+)", &v));
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch("32768",  "(-?\\d+)", &v));
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint16 v;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("100",     "(\\d+)", &v));    CHECK_EQ(v, 100);
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("32767",   "(\\d+)", &v));    CHECK_EQ(v, 32767);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("65535",   "(\\d+)", &v));    CHECK_EQ(v, 65535);
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch("65536",  "(\\d+)", &v));
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 v;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const int32 max = 0x7fffffff;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const int32 min = -max - 1;
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("100",          "(-?\\d+)", &v)); CHECK_EQ(v, 100);
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("-100",         "(-?\\d+)", &v)); CHECK_EQ(v, -100);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("2147483647",   "(-?\\d+)", &v)); CHECK_EQ(v, max);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("-2147483648",  "(-?\\d+)", &v)); CHECK_EQ(v, min);
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch("-2147483649", "(-?\\d+)", &v));
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch("2147483648",  "(-?\\d+)", &v));
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch(zeros + "2147483647", "(-?\\d+)", &v));
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, max);
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("-" + zeros + "2147483648", "(-?\\d+)", &v));
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, min);
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch("-" + zeros + "2147483649", "(-?\\d+)", &v));
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("0x7fffffff", "(.*)", RE2::CRadix(&v)));
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, max);
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch("000x7fffffff", "(.*)", RE2::CRadix(&v)));
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 v;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const uint32 max = 0xfffffffful;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("100",         "(\\d+)", &v)); CHECK_EQ(v, 100);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("4294967295",  "(\\d+)", &v)); CHECK_EQ(v, max);
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch("4294967296", "(\\d+)", &v));
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch("-1",         "(\\d+)", &v));
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch(zeros + "4294967295", "(\\d+)", &v)); CHECK_EQ(v, max);
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 v;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const int64 max = 0x7fffffffffffffffull;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const int64 min = -max - 1;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char buf[32];
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("100",  "(-?\\d+)", &v)); CHECK_EQ(v, 100);
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("-100", "(-?\\d+)", &v)); CHECK_EQ(v, -100);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    snprintf(buf, sizeof(buf), "%lld", (long long int)max);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch(buf,    "(-?\\d+)", &v)); CHECK_EQ(v, max);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    snprintf(buf, sizeof(buf), "%lld", (long long int)min);
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch(buf,    "(-?\\d+)", &v)); CHECK_EQ(v, min);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    snprintf(buf, sizeof(buf), "%lld", (long long int)max);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert(buf[strlen(buf)-1] != '9');
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf[strlen(buf)-1]++;
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch(buf,   "(-?\\d+)", &v));
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    snprintf(buf, sizeof(buf), "%lld", (long long int)min);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert(buf[strlen(buf)-1] != '9');
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf[strlen(buf)-1]++;
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch(buf,   "(-?\\d+)", &v));
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint64 v;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 v2;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const uint64 max = 0xffffffffffffffffull;
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char buf[32];
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("100",  "(-?\\d+)", &v));  CHECK_EQ(v, 100);
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("-100", "(-?\\d+)", &v2)); CHECK_EQ(v2, -100);
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    snprintf(buf, sizeof(buf), "%llu", (long long unsigned)max);
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch(buf,    "(-?\\d+)", &v)); CHECK_EQ(v, max);
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert(buf[strlen(buf)-1] != '9');
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf[strlen(buf)-1]++;
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch(buf,   "(-?\\d+)", &v));
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FloatingPointFullMatchTypes) {
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string zeros(100, '0');
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    float v;
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("100",   "(.*)", &v));  CHECK_EQ(v, 100);
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("-100.", "(.*)", &v));  CHECK_EQ(v, -100);
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("1e23",  "(.*)", &v));  CHECK_EQ(v, float(1e23));
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch(zeros + "1e23",  "(.*)", &v));
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, float(1e23));
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 6700000000081920.1 is an edge case.
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 6700000000081920 is exactly halfway between
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // two float32s, so the .1 should make it round up.
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // However, the .1 is outside the precision possible with
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // a float64: the nearest float64 is 6700000000081920.
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // So if the code uses strtod and then converts to float32,
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // round-to-even will make it round down instead of up.
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // To pass the test, the parser must call strtof directly.
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This test case is carefully chosen to use only a 17-digit
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // number, since C does not guarantee to get the correctly
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // rounded answer for strtod and strtof unless the input is
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // short.
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("0.1", "(.*)", &v));
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, 0.1f) << StringPrintf("%.8g != %.8g", v, 0.1f);
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("6700000000081920.1", "(.*)", &v));
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, 6700000000081920.1f)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << StringPrintf("%.8g != %.8g", v, 6700000000081920.1f);
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double v;
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("100",   "(.*)", &v));  CHECK_EQ(v, 100);
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("-100.", "(.*)", &v));  CHECK_EQ(v, -100);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("1e23",  "(.*)", &v));  CHECK_EQ(v, 1e23);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch(zeros + "1e23", "(.*)", &v));
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, double(1e23));
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("0.1", "(.*)", &v));
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, 0.1) << StringPrintf("%.17g != %.17g", v, 0.1);
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::FullMatch("1.00000005960464485", "(.*)", &v));
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(v, 1.0000000596046448)
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << StringPrintf("%.17g != %.17g", v, 1.0000000596046448);
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchAnchored) {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that matching is fully anchored
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("x1001", "(\\d+)",  &i));
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("1001x", "(\\d+)",  &i));
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("x1001",  "x(\\d+)", &i)); CHECK_EQ(i, 1001);
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("1001x",  "(\\d+)x", &i)); CHECK_EQ(i, 1001);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchBraces) {
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Braces
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("0abcd",  "[0-9a-f+.-]{5,}"));
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("0abcde", "[0-9a-f+.-]{5,}"));
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("0abc",  "[0-9a-f+.-]{5,}"));
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, Complicated) {
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complicated RE2
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("foo", "foo|bar|[A-Z]"));
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("bar", "foo|bar|[A-Z]"));
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("X",   "foo|bar|[A-Z]"));
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("XY", "foo|bar|[A-Z]"));
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchEnd) {
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check full-match handling (needs '$' tacked on internally)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("fo", "fo|foo"));
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("foo", "fo|foo"));
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("fo", "fo|foo$"));
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("foo", "fo|foo$"));
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("foo", "foo$"));
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("foo$bar", "foo\\$"));
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch("fox", "fo|bar"));
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Uncomment the following if we change the handling of '$' to
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // prevent it from matching a trailing newline
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (false) {
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check that we don't get bitten by pcre's special handling of a
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // '\n' at the end of the string matching '$'
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::PartialMatch("foo\n", "foo$"));
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, FullMatchArgCount) {
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Number of args
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int a[16];
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("", ""));
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(a, 0, sizeof(0));
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("1",
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "(\\d){1}",
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[0]));
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[0], 1);
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(a, 0, sizeof(0));
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("12",
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "(\\d)(\\d)",
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[0],  &a[1]));
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[0], 1);
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[1], 2);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(a, 0, sizeof(0));
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("123",
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "(\\d)(\\d)(\\d)",
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[0],  &a[1],  &a[2]));
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[0], 1);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[1], 2);
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[2], 3);
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(a, 0, sizeof(0));
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("1234",
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "(\\d)(\\d)(\\d)(\\d)",
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[0],  &a[1],  &a[2],  &a[3]));
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[0], 1);
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[1], 2);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[2], 3);
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[3], 4);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(a, 0, sizeof(0));
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("12345",
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "(\\d)(\\d)(\\d)(\\d)(\\d)",
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[0],  &a[1],  &a[2],  &a[3],
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[4]));
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[0], 1);
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[1], 2);
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[2], 3);
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[3], 4);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[4], 5);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(a, 0, sizeof(0));
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("123456",
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)",
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[0],  &a[1],  &a[2],  &a[3],
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[4],  &a[5]));
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[0], 1);
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[1], 2);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[2], 3);
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[3], 4);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[4], 5);
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[5], 6);
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(a, 0, sizeof(0));
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("1234567",
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)",
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[0],  &a[1],  &a[2],  &a[3],
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[4],  &a[5],  &a[6]));
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[0], 1);
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[1], 2);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[2], 3);
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[3], 4);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[4], 5);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[5], 6);
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[6], 7);
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(a, 0, sizeof(0));
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch("1234567890123456",
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)"
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)",
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[0],  &a[1],  &a[2],  &a[3],
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[4],  &a[5],  &a[6],  &a[7],
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[8],  &a[9],  &a[10], &a[11],
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &a[12], &a[13], &a[14], &a[15]));
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[0], 1);
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[1], 2);
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[2], 3);
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[3], 4);
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[4], 5);
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[5], 6);
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[6], 7);
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[7], 8);
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[8], 9);
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[9], 0);
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[10], 1);
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[11], 2);
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[12], 3);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[13], 4);
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[14], 5);
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(a[15], 6);
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, Accessors) {
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the pattern() accessor
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string kPattern = "http://([^/]+)/.*";
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const RE2 re(kPattern);
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(kPattern, re.pattern());
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check RE2 error field.
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re("foo");
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(re.error().empty());  // Must have no error
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(re.ok());
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(re.error_code() == RE2::NoError);
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, UTF8) {
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check UTF-8 handling
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Three Japanese characters (nihongo)
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char utf8_string[] = {
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       0xe6, 0x97, 0xa5, // 65e5
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       0xe6, 0x9c, 0xac, // 627c
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       0xe8, 0xaa, 0x9e, // 8a9e
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       0
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char utf8_pattern[] = {
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       '.',
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       0xe6, 0x9c, 0xac, // 627c
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       '.',
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       0
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both should match in either mode, bytes or UTF-8
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re_test1(".........", RE2::Latin1);
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch(utf8_string, re_test1));
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re_test2("...");
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch(utf8_string, re_test2));
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that '.' matches one byte or UTF-8 character
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // according to the mode.
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string s;
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re_test3("(.)", RE2::Latin1);
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch(utf8_string, re_test3, &s));
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(s, string("\xe6"));
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re_test4("(.)");
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch(utf8_string, re_test4, &s));
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(s, string("\xe6\x97\xa5"));
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that string matches itself in either mode
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re_test5(utf8_string, RE2::Latin1);
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch(utf8_string, re_test5));
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re_test6(utf8_string);
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch(utf8_string, re_test6));
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that pattern matches string only in UTF8 mode
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re_test7(utf8_pattern, RE2::Latin1);
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(!RE2::FullMatch(utf8_string, re_test7));
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re_test8(utf8_pattern);
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch(utf8_string, re_test8));
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, UngreedyUTF8) {
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that ungreedy, UTF8 regular expressions don't match when they
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // oughtn't -- see bug 82246.
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This code always worked.
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* pattern = "\\w+X";
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string target = "a aX";
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 match_sentence(pattern, RE2::Latin1);
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 match_sentence_re(pattern);
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch(target, match_sentence));
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch(target, match_sentence_re));
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* pattern = "(?U)\\w+X";
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string target = "a aX";
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 match_sentence(pattern, RE2::Latin1);
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(match_sentence.error(), "");
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 match_sentence_re(pattern);
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch(target, match_sentence));
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::FullMatch(target, match_sentence_re));
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, Rejects) {
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { RE2 re("a\\1", RE2::Quiet); CHECK(!re.ok()); }
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re("a[x", RE2::Quiet);
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!re.ok());
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re("a[z-a]", RE2::Quiet);
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!re.ok());
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re("a[[:foobar:]]", RE2::Quiet);
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!re.ok());
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re("a(b", RE2::Quiet);
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!re.ok());
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re("a\\", RE2::Quiet);
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!re.ok());
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, NoCrash) {
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that using a bad regexp doesn't crash.
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re("a\\", RE2::Quiet);
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!re.ok());
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::PartialMatch("a\\b", re));
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that using an enormous regexp doesn't crash
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re("(((.{100}){100}){100}){100}", RE2::Quiet);
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!re.ok());
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!RE2::PartialMatch("aaa", re));
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that a crazy regexp still compiles and runs.
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re(".{512}x", RE2::Quiet);
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(re.ok());
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string s;
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    s.append(515, 'c');
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    s.append("x");
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(RE2::PartialMatch(s, re));
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, Recursion) {
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that recursion is stopped.
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test is PCRE-legacy -- there's no recursion in RE2.
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes = 15 * 1024;  // enough to crash PCRE
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRecursion(bytes, ".");
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRecursion(bytes, "a");
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRecursion(bytes, "a.");
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRecursion(bytes, "ab.");
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRecursion(bytes, "abc.");
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, BigCountedRepetition) {
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that counted repetition works, given tons of memory.
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2::Options opt;
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  opt.set_max_mem(256<<20);
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re(".{512}x", opt);
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(re.ok());
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string s;
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  s.append(515, 'c');
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  s.append("x");
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::PartialMatch(s, re));
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, DeepRecursion) {
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test for deep stack recursion.  This would fail with a
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // segmentation violation due to stack overflow before pcre was
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // patched.
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Again, a PCRE legacy test.  RE2 doesn't recurse.
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string comment("x*");
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string a(131072, 'a');
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  comment += a;
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  comment += "*x";
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re("((?:\\s|xx.*\n|x[*](?:\n|.)*?[*]x)*)");
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(RE2::FullMatch(comment, re));
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Suggested by Josh Hyman.  Failed when SearchOnePass was
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not implementing case-folding.
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CaseInsensitive, MatchAndConsume) {
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string result;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string text = "A fish named *Wanda*";
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece sp(text);
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatch(sp, "(?i)([wand]{5})", &result));
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FindAndConsume(&sp, "(?i)([wand]{5})", &result));
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RE2 should permit implicit conversions from string, StringPiece, const char*,
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and C string literals.
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, ImplicitConversions) {
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string re_string(".");
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece re_stringpiece(".");
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* re_cstring = ".";
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatch("e", re_string));
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatch("e", re_stringpiece));
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatch("e", re_cstring));
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatch("e", "."));
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Bugs introduced by 8622304
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, CL8622304) {
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reported by ingow
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string dir;
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("D", "([^\\\\])"));  // ok
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("D", "([^\\\\])", &dir));  // fails
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reported by jacobsa
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string key, val;
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatch("bar:1,0x2F,030,4,5;baz:true;fooby:false,true",
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "(\\w+)(?::((?:[^;\\\\]|\\\\.)*))?;?",
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &key,
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &val));
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(key, "bar");
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(val, "1,0x2F,030,4,5");
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that RE2 returns correct regexp pieces on error.
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In particular, make sure it returns whole runes
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and that it always reports invalid UTF-8.
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Also check that Perl error flag piece is big enough.
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct ErrorTest {
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *regexp;
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *error;
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} error_tests[] = {
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ab\\αcd", "\\α" },
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ef\\x☺01", "\\x☺0" },
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "gh\\x1☺01", "\\x1☺" },
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "ij\\x1", "\\x1" },
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "kl\\x", "\\x" },
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "uv\\x{0000☺}", "\\x{0000☺" },
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "wx\\p{ABC", "\\p{ABC" },
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "yz(?smiUX:abc)", "(?smiUX" },   // used to return (?s but the error is X
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "aa(?sm☺i", "(?sm☺" },
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "bb[abc", "[abc" },
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "mn\\x1\377", "" },  // no argument string returned for invalid UTF-8
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "op\377qr", "" },
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "st\\x{00000\377", "" },
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "zz\\p{\377}", "" },
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "zz\\x{00\377}", "" },
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "zz(?P<name\377>abc)", "" },
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, ErrorArgs) {
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < arraysize(error_tests); i++) {
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re(error_tests[i].regexp, RE2::Quiet);
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(re.ok());
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(re.error_arg(), error_tests[i].error) << re.error();
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that "never match \n" mode never matches \n.
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct NeverTest {
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* regexp;
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* text;
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* match;
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} never_tests[] = {
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "(.*)", "abc\ndef\nghi\n", "abc" },
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "(?s)(abc.*def)", "abc\ndef\n", NULL },
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "(abc(.|\n)*def)", "abc\ndef\n", NULL },
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "(abc[^x]*def)", "abc\ndef\n", NULL },
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "(abc[^x]*def)", "abczzzdef\ndef\n", "abczzzdef" },
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, NeverNewline) {
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2::Options opt;
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  opt.set_never_nl(true);
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < arraysize(never_tests); i++) {
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NeverTest& t = never_tests[i];
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RE2 re(t.regexp, opt);
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (t.match == NULL) {
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(re.PartialMatch(t.text, re));
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StringPiece m;
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(re.PartialMatch(t.text, re, &m));
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(m, t.match);
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that there are no capturing groups in "never capture" mode.
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, NeverCapture) {
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2::Options opt;
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  opt.set_never_capture(true);
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re("(r)(e)", opt);
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, re.NumberOfCapturingGroups());
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Bitstate bug was looking at submatch[0] even if nsubmatch == 0.
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Triggered by a failed DFA search falling back to Bitstate when
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// using Match with a NULL submatch set.  Bitstate tried to read
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the submatch[0] entry even if nsubmatch was 0.
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, BitstateCaptureBug) {
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2::Options opt;
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  opt.set_max_mem(20000);
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re("(_________$)", opt);
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece s = "xxxxxxxxxxxxxxxxxxxxxxxxxx_________x";
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(re.Match(s, 0, s.size(), RE2::UNANCHORED, NULL, 0));
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// C++ version of bug 609710.
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, UnicodeClasses) {
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const string str = "ABCDEFGHI譚永鋒";
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string a, b, c;
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("A", "\\p{L}"));
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("A", "\\p{Lu}"));
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("A", "\\p{Ll}"));
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("A", "\\P{L}"));
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("A", "\\P{Lu}"));
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("A", "\\P{Ll}"));
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("譚", "\\p{L}"));
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("譚", "\\p{Lu}"));
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("譚", "\\p{Ll}"));
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("譚", "\\P{L}"));
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("譚", "\\P{Lu}"));
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("譚", "\\P{Ll}"));
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("永", "\\p{L}"));
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("永", "\\p{Lu}"));
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("永", "\\p{Ll}"));
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("永", "\\P{L}"));
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("永", "\\P{Lu}"));
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("永", "\\P{Ll}"));
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("鋒", "\\p{L}"));
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("鋒", "\\p{Lu}"));
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("鋒", "\\p{Ll}"));
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::FullMatch("鋒", "\\P{L}"));
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("鋒", "\\P{Lu}"));
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch("鋒", "\\P{Ll}"));
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatch(str, "(.).*?(.).*?(.)", &a, &b, &c));
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("A", a);
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("B", b);
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("C", c);
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatch(str, "(.).*?([\\p{L}]).*?(.)", &a, &b, &c));
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("A", a);
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("B", b);
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("C", c);
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::PartialMatch(str, "\\P{L}"));
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatch(str, "(.).*?([\\p{Lu}]).*?(.)", &a, &b, &c));
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("A", a);
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("B", b);
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("C", c);
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::PartialMatch(str, "[^\\p{Lu}\\p{Lo}]"));
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::PartialMatch(str, ".*(.).*?([\\p{Lu}\\p{Lo}]).*?(.)", &a, &b, &c));
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("譚", a);
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("永", b);
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("鋒", c);
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Bug reported by saito. 2009/02/17
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, NullVsEmptyString) {
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re2(".*");
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece v1("");
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch(v1, re2));
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece v2;
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::FullMatch(v2, re2));
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Issue 1816809
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, Bug1816809) {
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re("(((((llx((-3)|(4)))(;(llx((-3)|(4))))*))))");
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringPiece piece("llx-3;llx4");
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string x;
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RE2::Consume(&piece, re, &x));
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Issue 3061120
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, Bug3061120) {
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re("(?i)\\W");
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::PartialMatch("x", re));  // always worked
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::PartialMatch("k", re));  // broke because of kelvin
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RE2::PartialMatch("s", re));  // broke because of latin long s
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, CapturingGroupNames) {
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Opening parentheses annotated with group IDs:
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //      12    3        45   6         7
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RE2 re("((abc)(?P<G2>)|((e+)(?P<G2>.*)(?P<G1>u+)))");
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(re.ok());
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const map<int, string>& have = re.CapturingGroupNames();
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, string> want;
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  want[3] = "G2";
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  want[6] = "G2";
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  want[7] = "G1";
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(want, have);
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RE2, RegexpToStringLossOfAnchor) {
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(RE2("^[a-c]at", RE2::POSIX).Regexp()->ToString(), "^[a-c]at");
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(RE2("^[a-c]at").Regexp()->ToString(), "(?-m:^)[a-c]at");
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(RE2("ca[t-z]$", RE2::POSIX).Regexp()->ToString(), "ca[t-z]$");
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(RE2("ca[t-z]$").Regexp()->ToString(), "ca[t-z](?-m:$)");
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace re2
1381