165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// Copyright (c) 2005, Google Inc.
265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// All rights reserved.
365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// Redistribution and use in source and binary forms, with or without
565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// modification, are permitted provided that the following conditions are
665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// met:
765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//     * Redistributions of source code must retain the above copyright
965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// notice, this list of conditions and the following disclaimer.
1065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//     * Redistributions in binary form must reproduce the above
1165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// copyright notice, this list of conditions and the following disclaimer
1265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// in the documentation and/or other materials provided with the
1365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// distribution.
1465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//     * Neither the name of Google Inc. nor the names of its
1565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// contributors may be used to endorse or promote products derived from
1665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// this software without specific prior written permission.
1765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
1865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
3065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// Author: Greg J. Badros
3165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//
3265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// Unittest for scanner, especially GetNextComments and GetComments()
3365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// functionality.
3465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
3565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#ifdef HAVE_CONFIG_H
3665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include "config.h"
3765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#endif
3865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
3965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include <stdio.h>
4065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include <string.h>      /* for strchr */
4165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include <string>
4265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include <vector>
4365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
4465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include "pcrecpp.h"
4565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include "pcre_stringpiece.h"
4665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#include "pcre_scanner.h"
4765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
4865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define FLAGS_unittest_stack_size   49152
4965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
5065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// Dies with a fatal error if the two values are not equal.
5165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich#define CHECK_EQ(a, b)  do {                                    \
5265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  if ( (a) != (b) ) {                                           \
5365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    fprintf(stderr, "%s:%d: Check failed because %s != %s\n",   \
5465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich            __FILE__, __LINE__, #a, #b);                        \
5565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    exit(1);                                                    \
5665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }                                                             \
5765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich} while (0)
5865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
5965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichusing std::vector;
6065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichusing pcrecpp::StringPiece;
6165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichusing pcrecpp::Scanner;
6265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
6365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestScanner() {
6465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const char input[] = "\n"
6565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                       "alpha = 1; // this sets alpha\n"
6665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                       "bravo = 2; // bravo is set here\n"
6765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                       "gamma = 33; /* and here is gamma */\n";
6865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
6965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  const char *re = "(\\w+) = (\\d+);";
7065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
7165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  Scanner s(input);
7265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string var;
7365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  int number;
7465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.SkipCXXComments();
7565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.set_save_comments(true);
7665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  vector<StringPiece> comments;
7765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
7865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.Consume(re, &var, &number);
7965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(var, "alpha");
8065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(number, 1);
8165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(s.LineNumber(), 3);
8265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.GetNextComments(&comments);
8365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments.size(), 1);
8465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
8565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  comments.resize(0);
8665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
8765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.Consume(re, &var, &number);
8865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(var, "bravo");
8965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(number, 2);
9065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.GetNextComments(&comments);
9165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments.size(), 1);
9265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments[0].as_string(), " // bravo is set here\n");
9365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  comments.resize(0);
9465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
9565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.Consume(re, &var, &number);
9665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(var, "gamma");
9765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(number, 33);
9865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.GetNextComments(&comments);
9965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments.size(), 1);
10065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments[0].as_string(), " /* and here is gamma */\n");
10165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  comments.resize(0);
10265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
10365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.GetComments(0, sizeof(input), &comments);
10465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments.size(), 3);
10565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
10665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments[1].as_string(), " // bravo is set here\n");
10765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n");
10865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  comments.resize(0);
10965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
11065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.GetComments(0, (int)(strchr(input, '/') - input), &comments);
11165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments.size(), 0);
11265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  comments.resize(0);
11365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
11465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.GetComments((int)(strchr(input, '/') - input - 1), sizeof(input),
11565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                &comments);
11665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments.size(), 3);
11765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
11865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments[1].as_string(), " // bravo is set here\n");
11965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments[2].as_string(), " /* and here is gamma */\n");
12065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  comments.resize(0);
12165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
12265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.GetComments((int)(strchr(input, '/') - input - 1),
12365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich                (int)(strchr(input + 1, '\n') - input + 1), &comments);
12465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments.size(), 1);
12565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(comments[0].as_string(), " // this sets alpha\n");
12665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  comments.resize(0);
12765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
12865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
12965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichstatic void TestBigComment() {
13065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string input;
13165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  for (int i = 0; i < 1024; ++i) {
13265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    char buf[1024];  // definitely big enough
13365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    sprintf(buf, "    # Comment %d\n", i);
13465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich    input += buf;
13565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  }
13665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  input += "name = value;\n";
13765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
13865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  Scanner s(input.c_str());
13965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.SetSkipExpression("\\s+|#.*\n");
14065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
14165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string name;
14265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  string value;
14365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  s.Consume("(\\w+) = (\\w+);", &name, &value);
14465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(name, "name");
14565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  CHECK_EQ(value, "value");
14665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
14765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
14865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich// TODO: also test scanner and big-comment in a thread with a
14965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich//       small stack size
15065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
15165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevichint main(int argc, char** argv) {
15265de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  (void)argc;
15365de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  (void)argv;
15465de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestScanner();
15565de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  TestBigComment();
15665de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
15765de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  // Done
15865de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  printf("OK\n");
15965de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich
16065de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich  return 0;
16165de34233da93a3d65c00b8aad3ff9aad44c57deNick Kralevich}
162