10d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin// Copyright 2006 The RE2 Authors.  All Rights Reserved.
20d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin// Use of this source code is governed by a BSD-style
30d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin// license that can be found in the LICENSE file.
40d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
50d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin// Test parse.cc, dump.cc, and tostring.cc.
60d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
70d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#include <string>
80d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#include <vector>
90d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#include "util/test.h"
100d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#include "re2/regexp.h"
110d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
120d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkinnamespace re2 {
130d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
140d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin// Test that overflowed ref counts work.
150d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander GutkinTEST(Regexp, BigRef) {
160d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  Regexp* re;
170d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  re = Regexp::Parse("x", Regexp::NoParseFlags, NULL);
180d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  for (int i = 0; i < 100000; i++)
190d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin    re->Incref();
200d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  for (int i = 0; i < 100000; i++)
210d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin    re->Decref();
220d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  CHECK_EQ(re->Ref(), 1);
230d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  re->Decref();
240d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin}
250d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
260d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin// Test that very large Concats work.
270d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin// Depends on overflowed ref counts working.
280d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander GutkinTEST(Regexp, BigConcat) {
290d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  Regexp* x;
300d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  x = Regexp::Parse("x", Regexp::NoParseFlags, NULL);
310d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  vector<Regexp*> v(90000, x);  // ToString bails out at 100000
320d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  for (int i = 0; i < v.size(); i++)
330d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin    x->Incref();
340d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  CHECK_EQ(x->Ref(), 1 + v.size()) << x->Ref();
350d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  Regexp* re = Regexp::Concat(&v[0], v.size(), Regexp::NoParseFlags);
360d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  CHECK_EQ(re->ToString(), string(v.size(), 'x'));
370d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  re->Decref();
380d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  CHECK_EQ(x->Ref(), 1) << x->Ref();
390d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  x->Decref();
400d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin}
410d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
420d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander GutkinTEST(Regexp, NamedCaptures) {
430d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  Regexp* x;
440d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  RegexpStatus status;
450d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  x = Regexp::Parse(
460d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      "(?P<g1>a+)|(e)(?P<g2>w*)+(?P<g1>b+)", Regexp::PerlX, &status);
470d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  EXPECT_TRUE(status.ok());
480d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  EXPECT_EQ(4, x->NumCaptures());
490d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  const map<string, int>* have = x->NamedCaptures();
500d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  EXPECT_TRUE(have != NULL);
510d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  EXPECT_EQ(2, have->size());  // there are only two named groups in
520d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin                               // the regexp: 'g1' and 'g2'.
530d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  map<string, int> want;
540d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  want["g1"] = 1;
550d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  want["g2"] = 3;
560d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  EXPECT_EQ(want, *have);
570d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  x->Decref();
580d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  delete have;
590d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin}
600d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
610d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander GutkinTEST(Regexp, CaptureNames) {
620d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  Regexp* x;
630d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  RegexpStatus status;
640d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  x = Regexp::Parse(
650d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin      "(?P<g1>a+)|(e)(?P<g2>w*)+(?P<g1>b+)", Regexp::PerlX, &status);
660d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  EXPECT_TRUE(status.ok());
670d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  EXPECT_EQ(4, x->NumCaptures());
680d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  const map<int, string>* have = x->CaptureNames();
690d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  EXPECT_TRUE(have != NULL);
700d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  EXPECT_EQ(3, have->size());
710d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  map<int, string> want;
720d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  want[1] = "g1";
730d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  want[3] = "g2";
740d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  want[4] = "g1";
750d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
760d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  EXPECT_EQ(want, *have);
770d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  x->Decref();
780d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin  delete have;
790d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin}
800d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin
810d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin}  // namespace re2
82