165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// -*- coding: utf-8 -*-
265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// Copyright (c) 2005 - 2010, Google Inc.
465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// All rights reserved.
565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// Redistribution and use in source and binary forms, with or without
765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// modification, are permitted provided that the following conditions are
865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// met:
965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
1065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//     * Redistributions of source code must retain the above copyright
1165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// notice, this list of conditions and the following disclaimer.
1265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//     * Redistributions in binary form must reproduce the above
1365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// copyright notice, this list of conditions and the following disclaimer
1465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// in the documentation and/or other materials provided with the
1565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// distribution.
1665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//     * Neither the name of Google Inc. nor the names of its
1765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// contributors may be used to endorse or promote products derived from
1865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// this software without specific prior written permission.
1965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
2065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
3265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// Author: Sanjay Ghemawat
3365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
3465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// TODO: Test extractions for PartialMatch/Consume
3565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
3665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef HAVE_CONFIG_H
3765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include "config.h"
3865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
3965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
4065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include <stdio.h>
4165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include <string.h>      /* for memset and strcmp */
4265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include <cassert>
4365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include <vector>
4465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include "pcrecpp.h"
4565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
4665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichusing pcrecpp::StringPiece;
4765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichusing pcrecpp::RE;
4865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichusing pcrecpp::RE_Options;
4965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichusing pcrecpp::Hex;
5065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichusing pcrecpp::Octal;
5165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichusing pcrecpp::CRadix;
5265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
5365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic bool VERBOSE_TEST  = false;
5465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
5565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// CHECK dies with a fatal error if condition is not true.  It is *not*
5665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// controlled by NDEBUG, so the check will be executed regardless of
5765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// compilation mode.  Therefore, it is safe to do things like:
5865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//    CHECK_EQ(fp->Write(x), 4)
5965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CHECK(condition) do {                           \
6065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if (!(condition)) {                                   \
6165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    fprintf(stderr, "%s:%d: Check failed: %s\n",        \
6265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich            __FILE__, __LINE__, #condition);            \
6365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    exit(1);                                            \
6465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }                                                     \
6565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} while (0)
6665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
6765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CHECK_EQ(a, b)   CHECK(a == b)
6865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
6965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Timing1(int num_iters) {
7065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Same pattern lots of times
7165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE pattern("ruby:\\d+");
7265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  StringPiece p("ruby:1234");
7365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  for (int j = num_iters; j > 0; j--) {
7465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(pattern.FullMatch(p));
7565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
7665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
7765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
7865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Timing2(int num_iters) {
7965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Same pattern lots of times
8065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE pattern("ruby:(\\d+)");
8165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  int i;
8265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  for (int j = num_iters; j > 0; j--) {
8365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(pattern.FullMatch("ruby:1234", &i));
8465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(i, 1234);
8565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
8665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
8765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
8865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Timing3(int num_iters) {
8965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string text_string;
9065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  for (int j = num_iters; j > 0; j--) {
9165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    text_string += "this is another line\n";
9265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
9365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
9465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE line_matcher(".*\n");
9565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string line;
9665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  StringPiece text(text_string);
9765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  int counter = 0;
9865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  while (line_matcher.Consume(&text)) {
9965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    counter++;
10065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
10165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Matched %d lines\n", counter);
10265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
10365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
10465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if 0  // uncomment this if you have a way of defining VirtualProcessSize()
10565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
10665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void LeakTest() {
10765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Check for memory leaks
10865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  unsigned long long initial_size = 0;
10965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  for (int i = 0; i < 100000; i++) {
11065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    if (i == 50000) {
11165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      initial_size = VirtualProcessSize();
11265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      printf("Size after 50000: %llu\n", initial_size);
11365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    }
11465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    char buf[100];  // definitely big enough
11565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    sprintf(buf, "pat%09d", i);
11665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE newre(buf);
11765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
11865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  uint64 final_size = VirtualProcessSize();
11965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Size after 100000: %llu\n", final_size);
12065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const double growth = double(final_size - initial_size) / final_size;
12165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Growth: %0.2f%%", growth * 100);
12265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(growth < 0.02);       // Allow < 2% growth
12365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
12465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
12565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
12665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
12765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void RadixTests() {
12865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing hex\n");
12965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
13065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CHECK_HEX(type, value) \
13165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  do { \
13265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    type v; \
13365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("([0-9a-fA-F]+)[uUlL]*").FullMatch(#value, Hex(&v))); \
13465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(v, 0x ## value); \
13565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("([0-9a-fA-FxX]+)[uUlL]*").FullMatch("0x" #value, CRadix(&v))); \
13665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(v, 0x ## value); \
13765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  } while(0)
13865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
13965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_HEX(short,              2bad);
14065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_HEX(unsigned short,     2badU);
14165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_HEX(int,                dead);
14265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_HEX(unsigned int,       deadU);
14365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_HEX(long,               7eadbeefL);
14465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_HEX(unsigned long,      deadbeefUL);
14565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef HAVE_LONG_LONG
14665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_HEX(long long,          12345678deadbeefLL);
14765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
14865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef HAVE_UNSIGNED_LONG_LONG
14965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_HEX(unsigned long long, cafebabedeadbeefULL);
15065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
15165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
15265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CHECK_HEX
15365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
15465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing octal\n");
15565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
15665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CHECK_OCTAL(type, value) \
15765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  do { \
15865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    type v; \
15965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("([0-7]+)[uUlL]*").FullMatch(#value, Octal(&v))); \
16065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(v, 0 ## value); \
16165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("([0-9a-fA-FxX]+)[uUlL]*").FullMatch("0" #value, CRadix(&v))); \
16265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(v, 0 ## value); \
16365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  } while(0)
16465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
16565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_OCTAL(short,              77777);
16665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_OCTAL(unsigned short,     177777U);
16765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_OCTAL(int,                17777777777);
16865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_OCTAL(unsigned int,       37777777777U);
16965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_OCTAL(long,               17777777777L);
17065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_OCTAL(unsigned long,      37777777777UL);
17165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef HAVE_LONG_LONG
17265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_OCTAL(long long,          777777777777777777777LL);
17365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
17465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef HAVE_UNSIGNED_LONG_LONG
17565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_OCTAL(unsigned long long, 1777777777777777777777ULL);
17665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
17765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
17865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CHECK_OCTAL
17965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
18065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing decimal\n");
18165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
18265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CHECK_DECIMAL(type, value) \
18365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  do { \
18465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    type v; \
18565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?[0-9]+)[uUlL]*").FullMatch(#value, &v)); \
18665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(v, value); \
18765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?[0-9a-fA-FxX]+)[uUlL]*").FullMatch(#value, CRadix(&v))); \
18865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(v, value); \
18965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  } while(0)
19065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
19165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_DECIMAL(short,              -1);
19265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_DECIMAL(unsigned short,     9999);
19365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_DECIMAL(int,                -1000);
19465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_DECIMAL(unsigned int,       12345U);
19565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_DECIMAL(long,               -10000000L);
19665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_DECIMAL(unsigned long,      3083324652U);
19765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef HAVE_LONG_LONG
19865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_DECIMAL(long long,          -100000000000000LL);
19965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
20065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef HAVE_UNSIGNED_LONG_LONG
20165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_DECIMAL(unsigned long long, 1234567890987654321ULL);
20265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
20365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
20465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#undef CHECK_DECIMAL
20565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
20665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
20765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
20865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestReplace() {
20965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing Replace\n");
21065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
21165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  struct ReplaceTest {
21265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const char *regexp;
21365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const char *rewrite;
21465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const char *original;
21565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const char *single;
21665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const char *global;
21765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    int global_count;         // the expected return value from ReplaceAll
21865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  };
21965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  static const ReplaceTest tests[] = {
22065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "(qu|[b-df-hj-np-tv-z]*)([a-z]+)",
22165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "\\2\\1ay",
22265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "the quick brown fox jumps over the lazy dogs.",
22365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "ethay quick brown fox jumps over the lazy dogs.",
22465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "ethay ickquay ownbray oxfay umpsjay overay ethay azylay ogsday.",
22565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      9 },
22665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "\\w+",
22765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "\\0-NOSPAM",
22865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "paul.haahr@google.com",
22965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "paul-NOSPAM.haahr@google.com",
23065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "paul-NOSPAM.haahr-NOSPAM@google-NOSPAM.com-NOSPAM",
23165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      4 },
23265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "^",
23365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "(START)",
23465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "foo",
23565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "(START)foo",
23665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "(START)foo",
23765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      1 },
23865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "^",
23965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "(START)",
24065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "",
24165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "(START)",
24265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "(START)",
24365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      1 },
24465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "$",
24565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "(END)",
24665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "",
24765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "(END)",
24865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "(END)",
24965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      1 },
25065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "b",
25165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
25265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "ababababab",
25365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "abbabababab",
25465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "abbabbabbabbabb",
25565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich       5 },
25665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "b",
25765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
25865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbbbbb",
25965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbbbbbb",
26065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbbbbbbbbbbb",
26165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      6 },
26265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "b+",
26365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
26465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbbbbb",
26565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
26665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
26765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      1 },
26865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "b*",
26965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
27065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbbbbb",
27165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
27265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbbb",
27365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      2 },
27465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "b*",
27565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
27665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "aaaaa",
27765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbaaaaa",
27865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbabbabbabbabbabb",
27965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      6 },
28065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "b*",
28165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
28265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "aa\naa\n",
28365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbaa\naa\n",
28465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbabbabb\nbbabbabb\nbb",
28565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      7 },
28665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "b*",
28765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
28865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "aa\raa\r",
28965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbaa\raa\r",
29065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbabbabb\rbbabbabb\rbb",
29165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      7 },
29265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "b*",
29365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
29465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "aa\r\naa\r\n",
29565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbaa\r\naa\r\n",
29665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bbabbabb\r\nbbabbabb\r\nbb",
29765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      7 },
29865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    // Check empty-string matching (it's tricky!)
29965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "aa|b*",
30065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "@",
30165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "aa",
30265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "@",
30365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "@@",
30465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      2 },
30565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "b*|aa",
30665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "@",
30765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "aa",
30865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "@aa",
30965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "@@@",
31065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      3 },
31165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF8
31265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "b*",
31365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
31465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8",   // utf8
31565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb\xE3\x83\x9B\xE3\x83\xBC\xE3\x83\xA0\xE3\x81\xB8",
31665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb\xE3\x83\x9B""bb""\xE3\x83\xBC""bb""\xE3\x83\xA0""bb""\xE3\x81\xB8""bb",
31765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      5 },
31865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "b*",
31965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb",
32065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n",   // utf8
32165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      "bb\xE3\x83\x9B\r\n\xE3\x83\xBC\r\xE3\x83\xA0\n\xE3\x81\xB8\r\n",
32265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      ("bb\xE3\x83\x9B""bb\r\nbb""\xE3\x83\xBC""bb\rbb""\xE3\x83\xA0"
32365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich       "bb\nbb""\xE3\x81\xB8""bb\r\nbb"),
32465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      9 },
32565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
32665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    { "", NULL, NULL, NULL, NULL, 0 }
32765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  };
32865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
32965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF8
33065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const bool support_utf8 = true;
33165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#else
33265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const bool support_utf8 = false;
33365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
33465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
33565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  for (const ReplaceTest *t = tests; t->original != NULL; ++t) {
33665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re(t->regexp, RE_Options(PCRE_NEWLINE_CRLF).set_utf8(support_utf8));
33765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    assert(re.error().empty());
33865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    string one(t->original);
33965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(re.Replace(t->rewrite, &one));
34065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(one, t->single);
34165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    string all(t->original);
34265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const int replace_count = re.GlobalReplace(t->rewrite, &all);
34365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(all, t->global);
34465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(replace_count, t->global_count);
34565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
34665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
34765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // One final test: test \r\n replacement when we're not in CRLF mode
34865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
34965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re("b*", RE_Options(PCRE_NEWLINE_CR).set_utf8(support_utf8));
35065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    assert(re.error().empty());
35165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    string all("aa\r\naa\r\n");
35265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(re.GlobalReplace("bb", &all), 9);
35365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(all, string("bbabbabb\rbb\nbbabbabb\rbb\nbb"));
35465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
35565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
35665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re("b*", RE_Options(PCRE_NEWLINE_LF).set_utf8(support_utf8));
35765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    assert(re.error().empty());
35865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    string all("aa\r\naa\r\n");
35965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(re.GlobalReplace("bb", &all), 9);
36065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(all, string("bbabbabb\rbb\nbbabbabb\rbb\nbb"));
36165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
36265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // TODO: test what happens when no PCRE_NEWLINE_* flag is set.
36365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  //       Alas, the answer depends on how pcre was compiled.
36465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
36565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
36665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestExtract() {
36765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing Extract\n");
36865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
36965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string s;
37065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
37165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(.*)@([^.]*)").Extract("\\2!\\1", "boris@kremvax.ru", &s));
37265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(s, "kremvax!boris");
37365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
37465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // check the RE interface as well
37565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE(".*").Extract("'\\0'", "foo", &s));
37665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(s, "'foo'");
37765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("bar").Extract("'\\0'", "baz", &s));
37865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(s, "'foo'");
37965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
38065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
38165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestConsume() {
38265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing Consume\n");
38365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
38465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string word;
38565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
38665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string s("   aaa b!@#$@#$cccc");
38765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  StringPiece input(s);
38865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
38965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE r("\\s*(\\w+)");    // matches a word, possibly proceeded by whitespace
39065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(r.Consume(&input, &word));
39165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word, "aaa");
39265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(r.Consume(&input, &word));
39365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word, "b");
39465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(! r.Consume(&input, &word));
39565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
39665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
39765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestFindAndConsume() {
39865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing FindAndConsume\n");
39965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
40065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string word;
40165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
40265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string s("   aaa b!@#$@#$cccc");
40365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  StringPiece input(s);
40465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
40565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE r("(\\w+)");      // matches a word
40665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(r.FindAndConsume(&input, &word));
40765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word, "aaa");
40865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(r.FindAndConsume(&input, &word));
40965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word, "b");
41065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(r.FindAndConsume(&input, &word));
41165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word, "cccc");
41265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(! r.FindAndConsume(&input, &word));
41365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
41465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
41565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestMatchNumberPeculiarity() {
41665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing match-number peculiarity\n");
41765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
41865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string word1;
41965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string word2;
42065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string word3;
42165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
42265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE r("(foo)|(bar)|(baz)");
42365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(r.PartialMatch("foo", &word1, &word2, &word3));
42465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word1, "foo");
42565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word2, "");
42665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word3, "");
42765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(r.PartialMatch("bar", &word1, &word2, &word3));
42865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word1, "");
42965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word2, "bar");
43065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word3, "");
43165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(r.PartialMatch("baz", &word1, &word2, &word3));
43265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word1, "");
43365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word2, "");
43465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(word3, "baz");
43565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!r.PartialMatch("f", &word1, &word2, &word3));
43665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
43765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string a;
43865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(foo)|hello").FullMatch("hello", &a));
43965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a, "");
44065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
44165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
44265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestRecursion() {
44365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing recursion\n");
44465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
44565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Get one string that passes (sometimes), one that never does.
44665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string text_good("abcdefghijk");
44765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string text_bad("acdefghijkl");
44865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
44965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // According to pcretest, matching text_good against (\w+)*b
45065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // requires match_limit of at least 8192, and match_recursion_limit
45165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // of at least 37.
45265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
45365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options_ml;
45465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options_ml.set_match_limit(8192);
45565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE re("(\\w+)*b", options_ml);
45665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re.PartialMatch(text_good) == true);
45765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re.PartialMatch(text_bad) == false);
45865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re.FullMatch(text_good) == false);
45965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re.FullMatch(text_bad) == false);
46065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
46165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options_ml.set_match_limit(1024);
46265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE re2("(\\w+)*b", options_ml);
46365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re2.PartialMatch(text_good) == false);   // because of match_limit
46465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re2.PartialMatch(text_bad) == false);
46565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re2.FullMatch(text_good) == false);
46665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re2.FullMatch(text_bad) == false);
46765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
46865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options_mlr;
46965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options_mlr.set_match_limit_recursion(50);
47065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE re3("(\\w+)*b", options_mlr);
47165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re3.PartialMatch(text_good) == true);
47265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re3.PartialMatch(text_bad) == false);
47365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re3.FullMatch(text_good) == false);
47465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re3.FullMatch(text_bad) == false);
47565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
47665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options_mlr.set_match_limit_recursion(10);
47765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE re4("(\\w+)*b", options_mlr);
47865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re4.PartialMatch(text_good) == false);
47965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re4.PartialMatch(text_bad) == false);
48065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re4.FullMatch(text_good) == false);
48165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re4.FullMatch(text_bad) == false);
48265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
48365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
48465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// A meta-quoted string, interpreted as a pattern, should always match
48565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// the original unquoted string.
48665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestQuoteMeta(string unquoted, RE_Options options = RE_Options()) {
48765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string quoted = RE::QuoteMeta(unquoted);
48865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE re(quoted, options);
48965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re.FullMatch(unquoted));
49065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
49165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
49265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// A string containing meaningful regexp characters, which is then meta-
49365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// quoted, should not generally match a string the unquoted string does.
49465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void NegativeTestQuoteMeta(string unquoted, string should_not_match,
49565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                  RE_Options options = RE_Options()) {
49665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string quoted = RE::QuoteMeta(unquoted);
49765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE re(quoted, options);
49865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!re.FullMatch(should_not_match));
49965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
50065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
50165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// Tests that quoted meta characters match their original strings,
50265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// and that a few things that shouldn't match indeed do not.
50365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestQuotaMetaSimple() {
50465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("foo");
50565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("foo.bar");
50665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("foo\\.bar");
50765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("[1-9]");
50865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("1.5-2.0?");
50965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("\\d");
51065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("Who doesn't like ice cream?");
51165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("((a|b)c?d*e+[f-h]i)");
51265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("((?!)xxx).*yyy");
51365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("([");
51465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta(string("foo\0bar", 7));
51565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
51665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
51765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestQuoteMetaSimpleNegative() {
51865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("foo", "bar");
51965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("...", "bar");
52065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("\\.", ".");
52165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("\\.", "..");
52265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("(a)", "a");
52365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("(a|b)", "a");
52465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("(a|b)", "(a)");
52565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("(a|b)", "a|b");
52665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("[0-9]", "0");
52765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("[0-9]", "0-9");
52865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("[0-9]", "[9]");
52965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("((?!)xxx)", "xxx");
53065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
53165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
53265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestQuoteMetaLatin1() {
53365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("3\xb2 = 9");
53465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
53565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
53665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestQuoteMetaUtf8() {
53765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF8
53865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("Pl\xc3\xa1\x63ido Domingo", pcrecpp::UTF8());
53965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("xyz", pcrecpp::UTF8());            // No fancy utf8
54065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("\xc2\xb0", pcrecpp::UTF8());       // 2-byte utf8 (degree symbol)
54165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("27\xc2\xb0 degrees", pcrecpp::UTF8());  // As a middle character
54265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("\xe2\x80\xb3", pcrecpp::UTF8());   // 3-byte utf8 (double prime)
54365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("\xf0\x9d\x85\x9f", pcrecpp::UTF8()); // 4-byte utf8 (music note)
54465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMeta("27\xc2\xb0"); // Interpreted as Latin-1, but should still work
54565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  NegativeTestQuoteMeta("27\xc2\xb0",               // 2-byte utf (degree symbol)
54665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                        "27\\\xc2\\\xb0",
54765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                        pcrecpp::UTF8());
54865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
54965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
55065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
55165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestQuoteMetaAll() {
55265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing QuoteMeta\n");
55365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuotaMetaSimple();
55465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMetaSimpleNegative();
55565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMetaLatin1();
55665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMetaUtf8();
55765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
55865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
55965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
56065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// Options tests contributed by
56165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// Giuseppe Maxia, CTO, Stardata s.r.l.
56265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// July 2005
56365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
56465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void GetOneOptionResult(
56565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                const char *option_name,
56665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                const char *regex,
56765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                const char *str,
56865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                RE_Options options,
56965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                bool full,
57065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                string expected) {
57165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
57265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing Option <%s>\n", option_name);
57365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if(VERBOSE_TEST)
57465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    printf("/%s/ finds \"%s\" within \"%s\" \n",
57565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    regex,
57665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    expected.c_str(),
57765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    str);
57865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string captured("");
57965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if (full)
58065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE(regex,options).FullMatch(str, &captured);
58165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  else
58265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE(regex,options).PartialMatch(str, &captured);
58365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(captured, expected);
58465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
58565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
58665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestOneOption(
58765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                const char *option_name,
58865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                const char *regex,
58965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                const char *str,
59065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                RE_Options options,
59165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                bool full,
59265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                bool assertive = true) {
59365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
59465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing Option <%s>\n", option_name);
59565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if (VERBOSE_TEST)
59665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    printf("'%s' %s /%s/ \n",
59765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                  str,
59865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                  (assertive? "matches" : "doesn't match"),
59965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                  regex);
60065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if (assertive) {
60165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    if (full)
60265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      CHECK(RE(regex,options).FullMatch(str));
60365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    else
60465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      CHECK(RE(regex,options).PartialMatch(str));
60565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  } else {
60665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    if (full)
60765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      CHECK(!RE(regex,options).FullMatch(str));
60865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    else
60965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      CHECK(!RE(regex,options).PartialMatch(str));
61065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
61165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
61265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
61365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Test_CASELESS() {
61465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options;
61565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options2;
61665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
61765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_caseless(true);
61865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("CASELESS (class)",  "HELLO",    "hello", options, false);
61965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("CASELESS (class2)", "HELLO",    "hello", options2.set_caseless(true), false);
62065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("CASELESS (class)",  "^[A-Z]+$", "Hello", options, false);
62165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
62265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("CASELESS (function)", "HELLO",    "hello", pcrecpp::CASELESS(), false);
62365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("CASELESS (function)", "^[A-Z]+$", "Hello", pcrecpp::CASELESS(), false);
62465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_caseless(false);
62565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("no CASELESS", "HELLO",    "hello", options, false, false);
62665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
62765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
62865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Test_MULTILINE() {
62965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options;
63065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options2;
63165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const char *str = "HELLO\n" "cruel\n" "world\n";
63265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
63365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_multiline(true);
63465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("MULTILINE (class)",    "^cruel$", str, options, false);
63565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("MULTILINE (class2)",   "^cruel$", str, options2.set_multiline(true), false);
63665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("MULTILINE (function)", "^cruel$", str, pcrecpp::MULTILINE(), false);
63765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_multiline(false);
63865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("no MULTILINE", "^cruel$", str, options, false, false);
63965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
64065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
64165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Test_DOTALL() {
64265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options;
64365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options2;
64465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const char *str = "HELLO\n" "cruel\n" "world";
64565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
64665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_dotall(true);
64765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("DOTALL (class)",    "HELLO.*world", str, options, true);
64865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("DOTALL (class2)",   "HELLO.*world", str, options2.set_dotall(true), true);
64965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("DOTALL (function)",    "HELLO.*world", str, pcrecpp::DOTALL(), true);
65065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_dotall(false);
65165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("no DOTALL", "HELLO.*world", str, options, true, false);
65265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
65365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
65465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Test_DOLLAR_ENDONLY() {
65565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options;
65665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options2;
65765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const char *str = "HELLO world\n";
65865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
65965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("no DOLLAR_ENDONLY", "world$", str, options, false);
66065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_dollar_endonly(true);
66165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("DOLLAR_ENDONLY 1",    "world$", str, options, false, false);
66265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("DOLLAR_ENDONLY 2",    "world$", str, options2.set_dollar_endonly(true), false, false);
66365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
66465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
66565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Test_EXTRA() {
66665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options;
66765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const char *str = "HELLO";
66865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
66965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_extra(true);
67065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("EXTRA 1", "\\HELL\\O", str, options, true, false );
67165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("EXTRA 2", "\\HELL\\O", str, RE_Options().set_extra(true), true, false );
67265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_extra(false);
67365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("no EXTRA", "\\HELL\\O", str, options, true );
67465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
67565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
67665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Test_EXTENDED() {
67765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options;
67865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options2;
67965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const char *str = "HELLO world";
68065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
68165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_extended(true);
68265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("EXTENDED (class)",    "HELLO world", str, options, false, false);
68365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("EXTENDED (class2)",   "HELLO world", str, options2.set_extended(true), false, false);
68465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("EXTENDED (class)",
68565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    "^ HE L{2} O "
68665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    "\\s+        "
68765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    "\\w+ $      ",
68865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    str,
68965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    options,
69065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    false);
69165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
69265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("EXTENDED (function)",    "HELLO world", str, pcrecpp::EXTENDED(), false, false);
69365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("EXTENDED (function)",
69465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    "^ HE L{2} O "
69565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    "\\s+        "
69665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    "\\w+ $      ",
69765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    str,
69865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    pcrecpp::EXTENDED(),
69965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                    false);
70065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
70165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_extended(false);
70265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("no EXTENDED", "HELLO world", str, options, false);
70365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
70465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
70565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Test_NO_AUTO_CAPTURE() {
70665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options;
70765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const char *str = "HELLO world";
70865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string captured;
70965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
71065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing Option <no NO_AUTO_CAPTURE>\n");
71165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if (VERBOSE_TEST)
71265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    printf("parentheses capture text\n");
71365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE re("(world|universe)$", options);
71465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(re.Extract("\\1", str , &captured));
71565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(captured, "world");
71665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_no_auto_capture(true);
71765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("testing Option <NO_AUTO_CAPTURE>\n");
71865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if (VERBOSE_TEST)
71965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    printf("parentheses do not capture text\n");
72065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  re.Extract("\\1",str, &captured );
72165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(captured, "world");
72265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
72365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
72465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Test_UNGREEDY() {
72565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options;
72665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const char *str = "HELLO, 'this' is the 'world'";
72765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
72865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_ungreedy(true);
72965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  GetOneOptionResult("UNGREEDY 1", "('.*')", str, options, false, "'this'" );
73065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  GetOneOptionResult("UNGREEDY 2", "('.*')", str, RE_Options().set_ungreedy(true), false, "'this'" );
73165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  GetOneOptionResult("UNGREEDY", "('.*?')", str, options, false, "'this' is the 'world'" );
73265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
73365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_ungreedy(false);
73465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  GetOneOptionResult("no UNGREEDY", "('.*')", str, options, false, "'this' is the 'world'" );
73565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  GetOneOptionResult("no UNGREEDY", "('.*?')", str, options, false, "'this'" );
73665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
73765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
73865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void Test_all_options() {
73965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const char *str = "HELLO\n" "cruel\n" "world";
74065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options;
74165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_all_options(PCRE_CASELESS | PCRE_DOTALL);
74265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
74365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("all_options (CASELESS|DOTALL)", "^hello.*WORLD", str , options, false);
74465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_all_options(0);
74565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("all_options (0)", "^hello.*WORLD", str , options, false, false);
74665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_all_options(PCRE_MULTILINE | PCRE_EXTENDED);
74765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
74865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("all_options (MULTILINE|EXTENDED)", " ^ c r u e l $ ", str, options, false);
74965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("all_options (MULTILINE|EXTENDED) with constructor",
75065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                  " ^ c r u e l $ ",
75165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                  str,
75265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                  RE_Options(PCRE_MULTILINE | PCRE_EXTENDED),
75365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                  false);
75465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
75565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("all_options (MULTILINE|EXTENDED) with concatenation",
75665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                  " ^ c r u e l $ ",
75765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                  str,
75865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                  RE_Options()
75965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                       .set_multiline(true)
76065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                       .set_extended(true),
76165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                  false);
76265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
76365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_all_options(0);
76465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOneOption("all_options (0)", "^ c r u e l $", str, options, false, false);
76565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
76665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
76765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
76865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestOptions() {
76965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing Options\n");
77065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  Test_CASELESS();
77165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  Test_MULTILINE();
77265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  Test_DOTALL();
77365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  Test_DOLLAR_ENDONLY();
77465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  Test_EXTENDED();
77565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  Test_NO_AUTO_CAPTURE();
77665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  Test_UNGREEDY();
77765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  Test_EXTRA();
77865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  Test_all_options();
77965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
78065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
78165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestConstructors() {
78265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing constructors\n");
78365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
78465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE_Options options;
78565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  options.set_dotall(true);
78665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const char *str = "HELLO\n" "cruel\n" "world";
78765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
78865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE orig("HELLO.*world", options);
78965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(orig.FullMatch(str));
79065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
79165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE copy1(orig);
79265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(copy1.FullMatch(str));
79365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
79465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RE copy2("not a match");
79565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!copy2.FullMatch(str));
79665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  copy2 = copy1;
79765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(copy2.FullMatch(str));
79865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  copy2 = orig;
79965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(copy2.FullMatch(str));
80065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
80165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Make sure when we assign to ourselves, nothing bad happens
80265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  orig = orig;
80365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  copy1 = copy1;
80465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  copy2 = copy2;
80565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(orig.FullMatch(str));
80665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(copy1.FullMatch(str));
80765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(copy2.FullMatch(str));
80865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
80965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
81065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint main(int argc, char** argv) {
81165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Treat any flag as --help
81265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if (argc > 1 && argv[1][0] == '-') {
81365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    printf("Usage: %s [timing1|timing2|timing3 num-iters]\n"
81465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich           "       If 'timingX ###' is specified, run the given timing test\n"
81565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich           "       with the given number of iterations, rather than running\n"
81665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich           "       the default corectness test.\n", argv[0]);
81765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    return 0;
81865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
81965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
82065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if (argc > 1) {
82165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    if ( argc == 2 || atoi(argv[2]) == 0) {
82265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      printf("timing mode needs a num-iters argument\n");
82365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      return 1;
82465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    }
82565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    if (!strcmp(argv[1], "timing1"))
82665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      Timing1(atoi(argv[2]));
82765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    else if (!strcmp(argv[1], "timing2"))
82865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      Timing2(atoi(argv[2]));
82965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    else if (!strcmp(argv[1], "timing3"))
83065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      Timing3(atoi(argv[2]));
83165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    else
83265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich      printf("Unknown argument '%s'\n", argv[1]);
83365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    return 0;
83465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
83565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
83665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("PCRE C++ wrapper tests\n");
83765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing FullMatch\n");
83865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
83965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  int i;
84065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string s;
84165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
84265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  /***** FullMatch with no args *****/
84365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
84465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("h.*o").FullMatch("hello"));
84565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("h.*o").FullMatch("othello"));     // Must be anchored at front
84665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("h.*o").FullMatch("hello!"));      // Must be anchored at end
84765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("a*").FullMatch("aaaa"));           // Fullmatch with normal op
84865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("a*?").FullMatch("aaaa"));          // Fullmatch with nongreedy op
84965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("a*?\\z").FullMatch("aaaa"));       // Two unusual ops
85065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
85165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  /***** FullMatch with args *****/
85265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
85365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Zero-arg
85465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("\\d+").FullMatch("1001"));
85565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
85665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Single-arg
85765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d+)").FullMatch("1001",   &i));
85865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(i, 1001);
85965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(-?\\d+)").FullMatch("-123", &i));
86065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(i, -123);
86165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("()\\d+").FullMatch("10", &i));
86265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("(\\d+)").FullMatch("1234567890123456789012345678901234567890",
86365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                &i));
86465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
86565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Digits surrounding integer-arg
86665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("1(\\d*)4").FullMatch("1234", &i));
86765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(i, 23);
86865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d)\\d+").FullMatch("1234", &i));
86965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(i, 1);
87065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(-\\d)\\d+").FullMatch("-1234", &i));
87165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(i, -1);
87265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d)").PartialMatch("1234", &i));
87365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(i, 1);
87465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(-\\d)").PartialMatch("-1234", &i));
87565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(i, -1);
87665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
87765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // String-arg
87865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("h(.*)o").FullMatch("hello", &s));
87965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(s, string("ell"));
88065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
88165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // StringPiece-arg
88265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  StringPiece sp;
88365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\w+):(\\d+)").FullMatch("ruby:1234", &sp, &i));
88465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(sp.size(), 4);
88565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(memcmp(sp.data(), "ruby", 4) == 0);
88665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(i, 1234);
88765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
88865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Multi-arg
88965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\w+):(\\d+)").FullMatch("ruby:1234", &s, &i));
89065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(s, string("ruby"));
89165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(i, 1234);
89265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
89365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Ignore non-void* NULL arg
89465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("he(.*)lo").FullMatch("hello", (char*)NULL));
89565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("h(.*)o").FullMatch("hello", (string*)NULL));
89665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("h(.*)o").FullMatch("hello", (StringPiece*)NULL));
89765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(.*)").FullMatch("1234", (int*)NULL));
89865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef HAVE_LONG_LONG
89965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(.*)").FullMatch("1234567890123456", (long long*)NULL));
90065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
90165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(.*)").FullMatch("123.4567890123456", (double*)NULL));
90265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(.*)").FullMatch("123.4567890123456", (float*)NULL));
90365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
90465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Fail on non-void* NULL arg if the match doesn't parse for the given type.
90565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("h(.*)lo").FullMatch("hello", &s, (char*)NULL));
90665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("(.*)").FullMatch("hello", (int*)NULL));
90765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("(.*)").FullMatch("1234567890123456", (int*)NULL));
90865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("(.*)").FullMatch("hello", (double*)NULL));
90965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("(.*)").FullMatch("hello", (float*)NULL));
91065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
91165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Ignored arg
91265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\w+)(:)(\\d+)").FullMatch("ruby:1234", &s, (void*)NULL, &i));
91365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(s, string("ruby"));
91465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(i, 1234);
91565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
91665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Type tests
91765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
91865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    char c;
91965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(H)ello").FullMatch("Hello", &c));
92065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(c, 'H');
92165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
92265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
92365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    unsigned char c;
92465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(H)ello").FullMatch("Hello", &c));
92565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(c, static_cast<unsigned char>('H'));
92665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
92765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
92865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    short v;
92965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("100",     &v));    CHECK_EQ(v, 100);
93065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("-100",    &v));    CHECK_EQ(v, -100);
93165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("32767",   &v));    CHECK_EQ(v, 32767);
93265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("-32768",  &v));    CHECK_EQ(v, -32768);
93365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!RE("(-?\\d+)").FullMatch("-32769", &v));
93465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!RE("(-?\\d+)").FullMatch("32768",  &v));
93565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
93665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
93765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    unsigned short v;
93865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(\\d+)").FullMatch("100",     &v));    CHECK_EQ(v, 100);
93965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(\\d+)").FullMatch("32767",   &v));    CHECK_EQ(v, 32767);
94065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(\\d+)").FullMatch("65535",   &v));    CHECK_EQ(v, 65535);
94165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!RE("(\\d+)").FullMatch("65536",  &v));
94265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
94365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
94465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    int v;
94565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    static const int max_value = 0x7fffffff;
94665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    static const int min_value = -max_value - 1;
94765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("100",         &v)); CHECK_EQ(v, 100);
94865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("-100",        &v)); CHECK_EQ(v, -100);
94965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("2147483647",  &v)); CHECK_EQ(v, max_value);
95065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("-2147483648", &v)); CHECK_EQ(v, min_value);
95165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!RE("(-?\\d+)").FullMatch("-2147483649", &v));
95265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!RE("(-?\\d+)").FullMatch("2147483648",  &v));
95365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
95465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
95565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    unsigned int v;
95665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    static const unsigned int max_value = 0xfffffffful;
95765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(\\d+)").FullMatch("100",         &v)); CHECK_EQ(v, 100);
95865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(\\d+)").FullMatch("4294967295",  &v)); CHECK_EQ(v, max_value);
95965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!RE("(\\d+)").FullMatch("4294967296", &v));
96065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
96165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef HAVE_LONG_LONG
96265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich# if defined(__MINGW__) || defined(__MINGW32__)
96365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#   define LLD "%I64d"
96465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#   define LLU "%I64u"
96565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich# else
96665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#   define LLD "%lld"
96765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#   define LLU "%llu"
96865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich# endif
96965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
97065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    long long v;
97165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    static const long long max_value = 0x7fffffffffffffffLL;
97265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    static const long long min_value = -max_value - 1;
97365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    char buf[32];  // definitely big enough for a long long
97465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
97565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("100", &v)); CHECK_EQ(v, 100);
97665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("-100",&v)); CHECK_EQ(v, -100);
97765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
97865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    sprintf(buf, LLD, max_value);
97965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, max_value);
98065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
98165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    sprintf(buf, LLD, min_value);
98265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, min_value);
98365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
98465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    sprintf(buf, LLD, max_value);
98565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    assert(buf[strlen(buf)-1] != '9');
98665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    buf[strlen(buf)-1]++;
98765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!RE("(-?\\d+)").FullMatch(buf, &v));
98865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
98965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    sprintf(buf, LLD, min_value);
99065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    assert(buf[strlen(buf)-1] != '9');
99165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    buf[strlen(buf)-1]++;
99265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!RE("(-?\\d+)").FullMatch(buf, &v));
99365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
99465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
99565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#if defined HAVE_UNSIGNED_LONG_LONG && defined HAVE_LONG_LONG
99665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
99765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    unsigned long long v;
99865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    long long v2;
99965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    static const unsigned long long max_value = 0xffffffffffffffffULL;
100065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    char buf[32];  // definitely big enough for a unsigned long long
100165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
100265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("100",&v)); CHECK_EQ(v, 100);
100365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch("-100",&v2)); CHECK_EQ(v2, -100);
100465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
100565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    sprintf(buf, LLU, max_value);
100665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(-?\\d+)").FullMatch(buf,&v)); CHECK_EQ(v, max_value);
100765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
100865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    assert(buf[strlen(buf)-1] != '9');
100965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    buf[strlen(buf)-1]++;
101065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!RE("(-?\\d+)").FullMatch(buf, &v));
101165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
101265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
101365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
101465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    float v;
101565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(.*)").FullMatch("100", &v));
101665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(.*)").FullMatch("-100.", &v));
101765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(.*)").FullMatch("1e23", &v));
101865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
101965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
102065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    double v;
102165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(.*)").FullMatch("100", &v));
102265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(.*)").FullMatch("-100.", &v));
102365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(RE("(.*)").FullMatch("1e23", &v));
102465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
102565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
102665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Check that matching is fully anchored
102765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("(\\d+)").FullMatch("x1001",  &i));
102865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("(\\d+)").FullMatch("1001x",  &i));
102965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("x(\\d+)").FullMatch("x1001", &i)); CHECK_EQ(i, 1001);
103065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d+)x").FullMatch("1001x", &i)); CHECK_EQ(i, 1001);
103165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
103265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Braces
103365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("[0-9a-f+.-]{5,}").FullMatch("0abcd"));
103465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("[0-9a-f+.-]{5,}").FullMatch("0abcde"));
103565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("[0-9a-f+.-]{5,}").FullMatch("0abc"));
103665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
103765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Complicated RE
103865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("foo|bar|[A-Z]").FullMatch("foo"));
103965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("foo|bar|[A-Z]").FullMatch("bar"));
104065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("foo|bar|[A-Z]").FullMatch("X"));
104165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("foo|bar|[A-Z]").FullMatch("XY"));
104265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
104365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Check full-match handling (needs '$' tacked on internally)
104465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("fo|foo").FullMatch("fo"));
104565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("fo|foo").FullMatch("foo"));
104665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("fo|foo$").FullMatch("fo"));
104765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("fo|foo$").FullMatch("foo"));
104865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("foo$").FullMatch("foo"));
104965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("foo\\$").FullMatch("foo$bar"));
105065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(!RE("fo|bar").FullMatch("fox"));
105165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
105265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Uncomment the following if we change the handling of '$' to
105365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // prevent it from matching a trailing newline
105465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if (false) {
105565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    // Check that we don't get bitten by pcre's special handling of a
105665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    // '\n' at the end of the string matching '$'
105765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!RE("foo$").PartialMatch("foo\n"));
105865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
105965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
106065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Number of args
106165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  int a[16];
106265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("").FullMatch(""));
106365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
106465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  memset(a, 0, sizeof(0));
106565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d){1}").FullMatch("1",
106665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                 &a[0]));
106765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[0], 1);
106865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
106965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  memset(a, 0, sizeof(0));
107065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d)(\\d)").FullMatch("12",
107165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                   &a[0],  &a[1]));
107265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[0], 1);
107365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[1], 2);
107465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
107565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  memset(a, 0, sizeof(0));
107665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d)(\\d)(\\d)").FullMatch("123",
107765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                        &a[0],  &a[1],  &a[2]));
107865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[0], 1);
107965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[1], 2);
108065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[2], 3);
108165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
108265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  memset(a, 0, sizeof(0));
108365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d)(\\d)(\\d)(\\d)").FullMatch("1234",
108465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                             &a[0],  &a[1],  &a[2],  &a[3]));
108565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[0], 1);
108665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[1], 2);
108765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[2], 3);
108865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[3], 4);
108965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
109065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  memset(a, 0, sizeof(0));
109165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("12345",
109265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                                  &a[0],  &a[1],  &a[2],
109365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                                  &a[3],  &a[4]));
109465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[0], 1);
109565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[1], 2);
109665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[2], 3);
109765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[3], 4);
109865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[4], 5);
109965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
110065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  memset(a, 0, sizeof(0));
110165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("123456",
110265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                                       &a[0],  &a[1],  &a[2],
110365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                                       &a[3],  &a[4],  &a[5]));
110465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[0], 1);
110565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[1], 2);
110665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[2], 3);
110765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[3], 4);
110865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[4], 5);
110965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[5], 6);
111065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
111165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  memset(a, 0, sizeof(0));
111265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch("1234567",
111365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                                            &a[0],  &a[1],  &a[2],  &a[3],
111465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                                                            &a[4],  &a[5],  &a[6]));
111565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[0], 1);
111665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[1], 2);
111765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[2], 3);
111865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[3], 4);
111965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[4], 5);
112065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[5], 6);
112165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[6], 7);
112265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
112365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  memset(a, 0, sizeof(0));
112465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)"
112565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich           "(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)(\\d)").FullMatch(
112665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich               "1234567890123456",
112765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich               &a[0],  &a[1],  &a[2],  &a[3],
112865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich               &a[4],  &a[5],  &a[6],  &a[7],
112965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich               &a[8],  &a[9],  &a[10], &a[11],
113065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich               &a[12], &a[13], &a[14], &a[15]));
113165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[0], 1);
113265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[1], 2);
113365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[2], 3);
113465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[3], 4);
113565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[4], 5);
113665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[5], 6);
113765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[6], 7);
113865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[7], 8);
113965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[8], 9);
114065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[9], 0);
114165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[10], 1);
114265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[11], 2);
114365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[12], 3);
114465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[13], 4);
114565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[14], 5);
114665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(a[15], 6);
114765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
114865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  /***** PartialMatch *****/
114965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
115065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing PartialMatch\n");
115165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
115265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("h.*o").PartialMatch("hello"));
115365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("h.*o").PartialMatch("othello"));
115465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("h.*o").PartialMatch("hello!"));
115565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK(RE("((((((((((((((((((((x))))))))))))))))))))").PartialMatch("x"));
115665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
115765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  /***** other tests *****/
115865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
115965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  RadixTests();
116065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestReplace();
116165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestExtract();
116265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestConsume();
116365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestFindAndConsume();
116465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestQuoteMetaAll();
116565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestMatchNumberPeculiarity();
116665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
116765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Check the pattern() accessor
116865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
116965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const string kPattern = "http://([^/]+)/.*";
117065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const RE re(kPattern);
117165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(kPattern, re.pattern());
117265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
117365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
117465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Check RE error field.
117565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
117665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re("foo");
117765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(re.error().empty());  // Must have no error
117865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
117965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
118065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef SUPPORT_UTF8
118165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Check UTF-8 handling
118265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
118365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    printf("Testing UTF-8 handling\n");
118465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
118565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    // Three Japanese characters (nihongo)
118665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const unsigned char utf8_string[] = {
118765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich         0xe6, 0x97, 0xa5, // 65e5
118865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich         0xe6, 0x9c, 0xac, // 627c
118965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich         0xe8, 0xaa, 0x9e, // 8a9e
119065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich         0
119165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    };
119265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const unsigned char utf8_pattern[] = {
119365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich         '.',
119465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich         0xe6, 0x9c, 0xac, // 627c
119565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich         '.',
119665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich         0
119765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    };
119865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
119965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    // Both should match in either mode, bytes or UTF-8
120065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re_test1(".........");
120165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(re_test1.FullMatch(utf8_string));
120265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re_test2("...", pcrecpp::UTF8());
120365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(re_test2.FullMatch(utf8_string));
120465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
120565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    // Check that '.' matches one byte or UTF-8 character
120665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    // according to the mode.
120765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    string ss;
120865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re_test3("(.)");
120965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(re_test3.PartialMatch(utf8_string, &ss));
121065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(ss, string("\xe6"));
121165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re_test4("(.)", pcrecpp::UTF8());
121265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(re_test4.PartialMatch(utf8_string, &ss));
121365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK_EQ(ss, string("\xe6\x97\xa5"));
121465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
121565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    // Check that string matches itself in either mode
121665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re_test5(utf8_string);
121765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(re_test5.FullMatch(utf8_string));
121865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re_test6(utf8_string, pcrecpp::UTF8());
121965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(re_test6.FullMatch(utf8_string));
122065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
122165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    // Check that pattern matches string only in UTF8 mode
122265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re_test7(utf8_pattern);
122365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!re_test7.FullMatch(utf8_string));
122465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re_test8(utf8_pattern, pcrecpp::UTF8());
122565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(re_test8.FullMatch(utf8_string));
122665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
122765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
122865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Check that ungreedy, UTF8 regular expressions don't match when they
122965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // oughtn't -- see bug 82246.
123065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
123165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    // This code always worked.
123265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const char* pattern = "\\w+X";
123365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const string target = "a aX";
123465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE match_sentence(pattern);
123565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE match_sentence_re(pattern, pcrecpp::UTF8());
123665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
123765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!match_sentence.FullMatch(target));
123865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!match_sentence_re.FullMatch(target));
123965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
124065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
124165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
124265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const char* pattern = "(?U)\\w+X";
124365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    const string target = "a aX";
124465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE match_sentence(pattern);
124565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE match_sentence_re(pattern, pcrecpp::UTF8());
124665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
124765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!match_sentence.FullMatch(target));
124865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!match_sentence_re.FullMatch(target));
124965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
125065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif  /* def SUPPORT_UTF8 */
125165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
125265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("Testing error reporting\n");
125365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
125465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  { RE re("a\\1"); CHECK(!re.error().empty()); }
125565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
125665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re("a[x");
125765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!re.error().empty());
125865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
125965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
126065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re("a[z-a]");
126165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!re.error().empty());
126265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
126365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
126465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re("a[[:foobar:]]");
126565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!re.error().empty());
126665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
126765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
126865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re("a(b");
126965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!re.error().empty());
127065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
127165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  {
127265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    RE re("a\\");
127365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    CHECK(!re.error().empty());
127465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
127565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
127665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Test that recursion is stopped
127765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestRecursion();
127865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
127965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Test Options
128065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if (getenv("VERBOSE_TEST") != NULL)
128165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    VERBOSE_TEST  = true;
128265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestOptions();
128365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
128465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Test the constructors
128565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestConstructors();
128665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
128765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Done
128865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("OK\n");
128965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
129065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  return 0;
129165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
1292