/[pcre]/code/trunk/pcrecpp_unittest.cc
ViewVC logotype

Diff of /code/trunk/pcrecpp_unittest.cc

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 77 by nigel, Sat Feb 24 21:40:45 2007 UTC revision 87 by nigel, Sat Feb 24 21:41:21 2007 UTC
# Line 43  using pcrecpp::Hex; Line 43  using pcrecpp::Hex;
43  using pcrecpp::Octal;  using pcrecpp::Octal;
44  using pcrecpp::CRadix;  using pcrecpp::CRadix;
45    
46    static bool VERBOSE_TEST  = false;
47    
48  // CHECK dies with a fatal error if condition is not true.  It is *not*  // CHECK dies with a fatal error if condition is not true.  It is *not*
49  // controlled by NDEBUG, so the check will be executed regardless of  // controlled by NDEBUG, so the check will be executed regardless of
50  // compilation mode.  Therefore, it is safe to do things like:  // compilation mode.  Therefore, it is safe to do things like:
# Line 346  static void TestMatchNumberPeculiarity() Line 348  static void TestMatchNumberPeculiarity()
348    CHECK_EQ(a, "");    CHECK_EQ(a, "");
349  }  }
350    
351  static void TestRecursion(int size, const char *pattern, int match_limit) {  static void TestRecursion() {
352    printf("Testing recursion\n");    printf("Testing recursion\n");
353    
354    // Fill up a string repeating the pattern given    // Get one string that passes (sometimes), one that never does.
355    string domain;    string text_good("abcdefghijk");
356    domain.resize(size);    string text_bad("acdefghijkl");
357    int patlen = strlen(pattern);  
358    for (int i = 0; i < size; ++i) {    // According to pcretest, matching text_good against (\w+)*b
359      domain[i] = pattern[i % patlen];    // requires match_limit of at least 8192, and match_recursion_limit
360      // of at least 37.
361    
362      RE_Options options_ml;
363      options_ml.set_match_limit(8192);
364      RE re("(\\w+)*b", options_ml);
365      CHECK(re.PartialMatch(text_good) == true);
366      CHECK(re.PartialMatch(text_bad) == false);
367      CHECK(re.FullMatch(text_good) == false);
368      CHECK(re.FullMatch(text_bad) == false);
369    
370      options_ml.set_match_limit(1024);
371      RE re2("(\\w+)*b", options_ml);
372      CHECK(re2.PartialMatch(text_good) == false);   // because of match_limit
373      CHECK(re2.PartialMatch(text_bad) == false);
374      CHECK(re2.FullMatch(text_good) == false);
375      CHECK(re2.FullMatch(text_bad) == false);
376    
377      RE_Options options_mlr;
378      options_mlr.set_match_limit_recursion(50);
379      RE re3("(\\w+)*b", options_mlr);
380      CHECK(re3.PartialMatch(text_good) == true);
381      CHECK(re3.PartialMatch(text_bad) == false);
382      CHECK(re3.FullMatch(text_good) == false);
383      CHECK(re3.FullMatch(text_bad) == false);
384    
385      options_mlr.set_match_limit_recursion(10);
386      RE re4("(\\w+)*b", options_mlr);
387      CHECK(re4.PartialMatch(text_good) == false);
388      CHECK(re4.PartialMatch(text_bad) == false);
389      CHECK(re4.FullMatch(text_good) == false);
390      CHECK(re4.FullMatch(text_bad) == false);
391    }
392    
393    //
394    // Options tests contributed by
395    // Giuseppe Maxia, CTO, Stardata s.r.l.
396    // July 2005
397    //
398    static void GetOneOptionResult(
399                    const char *option_name,
400                    const char *regex,
401                    const char *str,
402                    RE_Options options,
403                    bool full,
404                    string expected) {
405    
406      printf("Testing Option <%s>\n", option_name);
407      if(VERBOSE_TEST)
408        printf("/%s/ finds \"%s\" within \"%s\" \n",
409                        regex,
410                        expected.c_str(),
411                        str);
412      string captured("");
413      if (full)
414        RE(regex,options).FullMatch(str, &captured);
415      else
416        RE(regex,options).PartialMatch(str, &captured);
417      CHECK_EQ(captured, expected);
418    }
419    
420    static void TestOneOption(
421                    const char *option_name,
422                    const char *regex,
423                    const char *str,
424                    RE_Options options,
425                    bool full,
426                    bool assertive = true) {
427    
428      printf("Testing Option <%s>\n", option_name);
429      if (VERBOSE_TEST)
430        printf("'%s' %s /%s/ \n",
431                      str,
432                      (assertive? "matches" : "doesn't match"),
433                      regex);
434      if (assertive) {
435        if (full)
436          CHECK(RE(regex,options).FullMatch(str));
437        else
438          CHECK(RE(regex,options).PartialMatch(str));
439      } else {
440        if (full)
441          CHECK(!RE(regex,options).FullMatch(str));
442        else
443          CHECK(!RE(regex,options).PartialMatch(str));
444    }    }
445    // Just make sure it doesn't crash due to too much recursion.  }
446    
447    static void Test_CASELESS() {
448      RE_Options options;
449      RE_Options options2;
450    
451      options.set_caseless(true);
452      TestOneOption("CASELESS (class)",  "HELLO",    "hello", options, false);
453      TestOneOption("CASELESS (class2)", "HELLO",    "hello", options2.set_caseless(true), false);
454      TestOneOption("CASELESS (class)",  "^[A-Z]+$", "Hello", options, false);
455    
456      TestOneOption("CASELESS (function)", "HELLO",    "hello", pcrecpp::CASELESS(), false);
457      TestOneOption("CASELESS (function)", "^[A-Z]+$", "Hello", pcrecpp::CASELESS(), false);
458      options.set_caseless(false);
459      TestOneOption("no CASELESS", "HELLO",    "hello", options, false, false);
460    }
461    
462    static void Test_MULTILINE() {
463      RE_Options options;
464      RE_Options options2;
465      const char *str = "HELLO\n" "cruel\n" "world\n";
466    
467      options.set_multiline(true);
468      TestOneOption("MULTILINE (class)",    "^cruel$", str, options, false);
469      TestOneOption("MULTILINE (class2)",   "^cruel$", str, options2.set_multiline(true), false);
470      TestOneOption("MULTILINE (function)", "^cruel$", str, pcrecpp::MULTILINE(), false);
471      options.set_multiline(false);
472      TestOneOption("no MULTILINE", "^cruel$", str, options, false, false);
473    }
474    
475    static void Test_DOTALL() {
476      RE_Options options;
477      RE_Options options2;
478      const char *str = "HELLO\n" "cruel\n" "world";
479    
480      options.set_dotall(true);
481      TestOneOption("DOTALL (class)",    "HELLO.*world", str, options, true);
482      TestOneOption("DOTALL (class2)",   "HELLO.*world", str, options2.set_dotall(true), true);
483      TestOneOption("DOTALL (function)",    "HELLO.*world", str, pcrecpp::DOTALL(), true);
484      options.set_dotall(false);
485      TestOneOption("no DOTALL", "HELLO.*world", str, options, true, false);
486    }
487    
488    static void Test_DOLLAR_ENDONLY() {
489      RE_Options options;
490      RE_Options options2;
491      const char *str = "HELLO world\n";
492    
493      TestOneOption("no DOLLAR_ENDONLY", "world$", str, options, false);
494      options.set_dollar_endonly(true);
495      TestOneOption("DOLLAR_ENDONLY 1",    "world$", str, options, false, false);
496      TestOneOption("DOLLAR_ENDONLY 2",    "world$", str, options2.set_dollar_endonly(true), false, false);
497    }
498    
499    static void Test_EXTRA() {
500    RE_Options options;    RE_Options options;
501    options.set_match_limit(match_limit);    const char *str = "HELLO";
502    RE re("([a-zA-Z0-9]|-)+(\\.([a-zA-Z0-9]|-)+)*(\\.)?", options);  
503    re.FullMatch(domain);    options.set_extra(true);
504      TestOneOption("EXTRA 1", "\\HELL\\O", str, options, true, false );
505      TestOneOption("EXTRA 2", "\\HELL\\O", str, RE_Options().set_extra(true), true, false );
506      options.set_extra(false);
507      TestOneOption("no EXTRA", "\\HELL\\O", str, options, true );
508    }
509    
510    static void Test_EXTENDED() {
511      RE_Options options;
512      RE_Options options2;
513      const char *str = "HELLO world";
514    
515      options.set_extended(true);
516      TestOneOption("EXTENDED (class)",    "HELLO world", str, options, false, false);
517      TestOneOption("EXTENDED (class2)",   "HELLO world", str, options2.set_extended(true), false, false);
518      TestOneOption("EXTENDED (class)",
519                        "^ HE L{2} O "
520                        "\\s+        "
521                        "\\w+ $      ",
522                        str,
523                        options,
524                        false);
525    
526      TestOneOption("EXTENDED (function)",    "HELLO world", str, pcrecpp::EXTENDED(), false, false);
527      TestOneOption("EXTENDED (function)",
528                        "^ HE L{2} O "
529                        "\\s+        "
530                        "\\w+ $      ",
531                        str,
532                        pcrecpp::EXTENDED(),
533                        false);
534    
535      options.set_extended(false);
536      TestOneOption("no EXTENDED", "HELLO world", str, options, false);
537    }
538    
539    static void Test_NO_AUTO_CAPTURE() {
540      RE_Options options;
541      const char *str = "HELLO world";
542      string captured;
543    
544      printf("Testing Option <no NO_AUTO_CAPTURE>\n");
545      if (VERBOSE_TEST)
546        printf("parentheses capture text\n");
547      RE re("(world|universe)$", options);
548      CHECK(re.Extract("\\1", str , &captured));
549      CHECK_EQ(captured, "world");
550      options.set_no_auto_capture(true);
551      printf("testing Option <NO_AUTO_CAPTURE>\n");
552      if (VERBOSE_TEST)
553        printf("parentheses do not capture text\n");
554      re.Extract("\\1",str, &captured );
555      CHECK_EQ(captured, "world");
556    }
557    
558    static void Test_UNGREEDY() {
559      RE_Options options;
560      const char *str = "HELLO, 'this' is the 'world'";
561    
562      options.set_ungreedy(true);
563      GetOneOptionResult("UNGREEDY 1", "('.*')", str, options, false, "'this'" );
564      GetOneOptionResult("UNGREEDY 2", "('.*')", str, RE_Options().set_ungreedy(true), false, "'this'" );
565      GetOneOptionResult("UNGREEDY", "('.*?')", str, options, false, "'this' is the 'world'" );
566    
567      options.set_ungreedy(false);
568      GetOneOptionResult("no UNGREEDY", "('.*')", str, options, false, "'this' is the 'world'" );
569      GetOneOptionResult("no UNGREEDY", "('.*?')", str, options, false, "'this'" );
570  }  }
571    
572    static void Test_all_options() {
573      const char *str = "HELLO\n" "cruel\n" "world";
574      RE_Options options;
575      options.set_all_options(PCRE_CASELESS | PCRE_DOTALL);
576    
577      TestOneOption("all_options (CASELESS|DOTALL)", "^hello.*WORLD", str , options, false);
578      options.set_all_options(0);
579      TestOneOption("all_options (0)", "^hello.*WORLD", str , options, false, false);
580      options.set_all_options(PCRE_MULTILINE | PCRE_EXTENDED);
581    
582      TestOneOption("all_options (MULTILINE|EXTENDED)", " ^ c r u e l $ ", str, options, false);
583      TestOneOption("all_options (MULTILINE|EXTENDED) with constructor",
584                      " ^ c r u e l $ ",
585                      str,
586                      RE_Options(PCRE_MULTILINE | PCRE_EXTENDED),
587                      false);
588    
589      TestOneOption("all_options (MULTILINE|EXTENDED) with concatenation",
590                      " ^ c r u e l $ ",
591                      str,
592                      RE_Options()
593                           .set_multiline(true)
594                           .set_extended(true),
595                      false);
596    
597      options.set_all_options(0);
598      TestOneOption("all_options (0)", "^ c r u e l $", str, options, false, false);
599    
600    }
601    
602    static void TestOptions() {
603      printf("Testing Options\n");
604      Test_CASELESS();
605      Test_MULTILINE();
606      Test_DOTALL();
607      Test_DOLLAR_ENDONLY();
608      Test_EXTENDED();
609      Test_NO_AUTO_CAPTURE();
610      Test_UNGREEDY();
611      Test_EXTRA();
612      Test_all_options();
613    }
614    
615  int main(int argc, char** argv) {  int main(int argc, char** argv) {
616    // Treat any flag as --help    // Treat any flag as --help
# Line 798  int main(int argc, char** argv) { Line 1046  int main(int argc, char** argv) {
1046      CHECK(!re.error().empty());      CHECK(!re.error().empty());
1047    }    }
1048    
1049    // Test that recursion is stopped: there will be some errors reported    // Test that recursion is stopped
1050    int matchlimit = 5000;    TestRecursion();
1051    int bytes = 15 * 1024;  // enough to crash if there was no match limit  
1052    TestRecursion(bytes, ".", matchlimit);    // Test Options
1053    TestRecursion(bytes, "a", matchlimit);    if (getenv("VERBOSE_TEST") != NULL)
1054    TestRecursion(bytes, "a.", matchlimit);      VERBOSE_TEST  = true;
1055    TestRecursion(bytes, "ab.", matchlimit);    TestOptions();
   TestRecursion(bytes, "abc.", matchlimit);  
1056    
1057    // Done    // Done
1058    printf("OK\n");    printf("OK\n");

Legend:
Removed from v.77  
changed lines
  Added in v.87

  ViewVC Help
Powered by ViewVC 1.1.5