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: |
365 |
re.FullMatch(domain); |
re.FullMatch(domain); |
366 |
} |
} |
367 |
|
|
368 |
|
// |
369 |
|
// Options tests contributed by |
370 |
|
// Giuseppe Maxia, CTO, Stardata s.r.l. |
371 |
|
// July 2005 |
372 |
|
// |
373 |
|
static void GetOneOptionResult( |
374 |
|
const char *option_name, |
375 |
|
const char *regex, |
376 |
|
const char *str, |
377 |
|
RE_Options options, |
378 |
|
bool full, |
379 |
|
string expected) { |
380 |
|
|
381 |
|
printf("Testing Option <%s>\n", option_name); |
382 |
|
if(VERBOSE_TEST) |
383 |
|
printf("/%s/ finds \"%s\" within \"%s\" \n", |
384 |
|
regex, |
385 |
|
expected.c_str(), |
386 |
|
str); |
387 |
|
string captured(""); |
388 |
|
if (full) |
389 |
|
RE(regex,options).FullMatch(str, &captured); |
390 |
|
else |
391 |
|
RE(regex,options).PartialMatch(str, &captured); |
392 |
|
CHECK_EQ(captured, expected); |
393 |
|
} |
394 |
|
|
395 |
|
static void TestOneOption( |
396 |
|
const char *option_name, |
397 |
|
const char *regex, |
398 |
|
const char *str, |
399 |
|
RE_Options options, |
400 |
|
bool full, |
401 |
|
bool assertive = true) { |
402 |
|
|
403 |
|
printf("Testing Option <%s>\n", option_name); |
404 |
|
if (VERBOSE_TEST) |
405 |
|
printf("'%s' %s /%s/ \n", |
406 |
|
str, |
407 |
|
(assertive? "matches" : "doesn't match"), |
408 |
|
regex); |
409 |
|
if (assertive) { |
410 |
|
if (full) |
411 |
|
CHECK(RE(regex,options).FullMatch(str)); |
412 |
|
else |
413 |
|
CHECK(RE(regex,options).PartialMatch(str)); |
414 |
|
} else { |
415 |
|
if (full) |
416 |
|
CHECK(!RE(regex,options).FullMatch(str)); |
417 |
|
else |
418 |
|
CHECK(!RE(regex,options).PartialMatch(str)); |
419 |
|
} |
420 |
|
} |
421 |
|
|
422 |
|
static void Test_CASELESS() { |
423 |
|
RE_Options options; |
424 |
|
RE_Options options2; |
425 |
|
|
426 |
|
options.set_caseless(true); |
427 |
|
TestOneOption("CASELESS (class)", "HELLO", "hello", options, false); |
428 |
|
TestOneOption("CASELESS (class2)", "HELLO", "hello", options2.set_caseless(true), false); |
429 |
|
TestOneOption("CASELESS (class)", "^[A-Z]+$", "Hello", options, false); |
430 |
|
|
431 |
|
TestOneOption("CASELESS (function)", "HELLO", "hello", pcrecpp::CASELESS(), false); |
432 |
|
TestOneOption("CASELESS (function)", "^[A-Z]+$", "Hello", pcrecpp::CASELESS(), false); |
433 |
|
options.set_caseless(false); |
434 |
|
TestOneOption("no CASELESS", "HELLO", "hello", options, false, false); |
435 |
|
} |
436 |
|
|
437 |
|
static void Test_MULTILINE() { |
438 |
|
RE_Options options; |
439 |
|
RE_Options options2; |
440 |
|
const char *str = "HELLO\n" "cruel\n" "world\n"; |
441 |
|
|
442 |
|
options.set_multiline(true); |
443 |
|
TestOneOption("MULTILINE (class)", "^cruel$", str, options, false); |
444 |
|
TestOneOption("MULTILINE (class2)", "^cruel$", str, options2.set_multiline(true), false); |
445 |
|
TestOneOption("MULTILINE (function)", "^cruel$", str, pcrecpp::MULTILINE(), false); |
446 |
|
options.set_multiline(false); |
447 |
|
TestOneOption("no MULTILINE", "^cruel$", str, options, false, false); |
448 |
|
} |
449 |
|
|
450 |
|
static void Test_DOTALL() { |
451 |
|
RE_Options options; |
452 |
|
RE_Options options2; |
453 |
|
const char *str = "HELLO\n" "cruel\n" "world"; |
454 |
|
|
455 |
|
options.set_dotall(true); |
456 |
|
TestOneOption("DOTALL (class)", "HELLO.*world", str, options, true); |
457 |
|
TestOneOption("DOTALL (class2)", "HELLO.*world", str, options2.set_dotall(true), true); |
458 |
|
TestOneOption("DOTALL (function)", "HELLO.*world", str, pcrecpp::DOTALL(), true); |
459 |
|
options.set_dotall(false); |
460 |
|
TestOneOption("no DOTALL", "HELLO.*world", str, options, true, false); |
461 |
|
} |
462 |
|
|
463 |
|
static void Test_DOLLAR_ENDONLY() { |
464 |
|
RE_Options options; |
465 |
|
RE_Options options2; |
466 |
|
const char *str = "HELLO world\n"; |
467 |
|
|
468 |
|
TestOneOption("no DOLLAR_ENDONLY", "world$", str, options, false); |
469 |
|
options.set_dollar_endonly(true); |
470 |
|
TestOneOption("DOLLAR_ENDONLY 1", "world$", str, options, false, false); |
471 |
|
TestOneOption("DOLLAR_ENDONLY 2", "world$", str, options2.set_dollar_endonly(true), false, false); |
472 |
|
} |
473 |
|
|
474 |
|
static void Test_EXTRA() { |
475 |
|
RE_Options options; |
476 |
|
const char *str = "HELLO"; |
477 |
|
|
478 |
|
options.set_extra(true); |
479 |
|
TestOneOption("EXTRA 1", "\\HELL\\O", str, options, true, false ); |
480 |
|
TestOneOption("EXTRA 2", "\\HELL\\O", str, RE_Options().set_extra(true), true, false ); |
481 |
|
options.set_extra(false); |
482 |
|
TestOneOption("no EXTRA", "\\HELL\\O", str, options, true ); |
483 |
|
} |
484 |
|
|
485 |
|
static void Test_EXTENDED() { |
486 |
|
RE_Options options; |
487 |
|
RE_Options options2; |
488 |
|
const char *str = "HELLO world"; |
489 |
|
|
490 |
|
options.set_extended(true); |
491 |
|
TestOneOption("EXTENDED (class)", "HELLO world", str, options, false, false); |
492 |
|
TestOneOption("EXTENDED (class2)", "HELLO world", str, options2.set_extended(true), false, false); |
493 |
|
TestOneOption("EXTENDED (class)", |
494 |
|
"^ HE L{2} O " |
495 |
|
"\\s+ " |
496 |
|
"\\w+ $ ", |
497 |
|
str, |
498 |
|
options, |
499 |
|
false); |
500 |
|
|
501 |
|
TestOneOption("EXTENDED (function)", "HELLO world", str, pcrecpp::EXTENDED(), false, false); |
502 |
|
TestOneOption("EXTENDED (function)", |
503 |
|
"^ HE L{2} O " |
504 |
|
"\\s+ " |
505 |
|
"\\w+ $ ", |
506 |
|
str, |
507 |
|
pcrecpp::EXTENDED(), |
508 |
|
false); |
509 |
|
|
510 |
|
options.set_extended(false); |
511 |
|
TestOneOption("no EXTENDED", "HELLO world", str, options, false); |
512 |
|
} |
513 |
|
|
514 |
|
static void Test_NO_AUTO_CAPTURE() { |
515 |
|
RE_Options options; |
516 |
|
const char *str = "HELLO world"; |
517 |
|
string captured; |
518 |
|
|
519 |
|
printf("Testing Option <no NO_AUTO_CAPTURE>\n"); |
520 |
|
if (VERBOSE_TEST) |
521 |
|
printf("parentheses capture text\n"); |
522 |
|
RE re("(world|universe)$", options); |
523 |
|
CHECK(re.Extract("\\1", str , &captured)); |
524 |
|
CHECK_EQ(captured, "world"); |
525 |
|
options.set_no_auto_capture(true); |
526 |
|
printf("testing Option <NO_AUTO_CAPTURE>\n"); |
527 |
|
if (VERBOSE_TEST) |
528 |
|
printf("parentheses do not capture text\n"); |
529 |
|
re.Extract("\\1",str, &captured ); |
530 |
|
CHECK_EQ(captured, "world"); |
531 |
|
} |
532 |
|
|
533 |
|
static void Test_UNGREEDY() { |
534 |
|
RE_Options options; |
535 |
|
const char *str = "HELLO, 'this' is the 'world'"; |
536 |
|
|
537 |
|
options.set_ungreedy(true); |
538 |
|
GetOneOptionResult("UNGREEDY 1", "('.*')", str, options, false, "'this'" ); |
539 |
|
GetOneOptionResult("UNGREEDY 2", "('.*')", str, RE_Options().set_ungreedy(true), false, "'this'" ); |
540 |
|
GetOneOptionResult("UNGREEDY", "('.*?')", str, options, false, "'this' is the 'world'" ); |
541 |
|
|
542 |
|
options.set_ungreedy(false); |
543 |
|
GetOneOptionResult("no UNGREEDY", "('.*')", str, options, false, "'this' is the 'world'" ); |
544 |
|
GetOneOptionResult("no UNGREEDY", "('.*?')", str, options, false, "'this'" ); |
545 |
|
} |
546 |
|
|
547 |
|
static void Test_all_options() { |
548 |
|
const char *str = "HELLO\n" "cruel\n" "world"; |
549 |
|
RE_Options options; |
550 |
|
options.set_all_options(PCRE_CASELESS | PCRE_DOTALL); |
551 |
|
|
552 |
|
TestOneOption("all_options (CASELESS|DOTALL)", "^hello.*WORLD", str , options, false); |
553 |
|
options.set_all_options(0); |
554 |
|
TestOneOption("all_options (0)", "^hello.*WORLD", str , options, false, false); |
555 |
|
options.set_all_options(PCRE_MULTILINE | PCRE_EXTENDED); |
556 |
|
|
557 |
|
TestOneOption("all_options (MULTILINE|EXTENDED)", " ^ c r u e l $ ", str, options, false); |
558 |
|
TestOneOption("all_options (MULTILINE|EXTENDED) with constructor", |
559 |
|
" ^ c r u e l $ ", |
560 |
|
str, |
561 |
|
RE_Options(PCRE_MULTILINE | PCRE_EXTENDED), |
562 |
|
false); |
563 |
|
|
564 |
|
TestOneOption("all_options (MULTILINE|EXTENDED) with concatenation", |
565 |
|
" ^ c r u e l $ ", |
566 |
|
str, |
567 |
|
RE_Options() |
568 |
|
.set_multiline(true) |
569 |
|
.set_extended(true), |
570 |
|
false); |
571 |
|
|
572 |
|
options.set_all_options(0); |
573 |
|
TestOneOption("all_options (0)", "^ c r u e l $", str, options, false, false); |
574 |
|
|
575 |
|
} |
576 |
|
|
577 |
|
static void TestOptions() { |
578 |
|
printf("Testing Options\n"); |
579 |
|
Test_CASELESS(); |
580 |
|
Test_MULTILINE(); |
581 |
|
Test_DOTALL(); |
582 |
|
Test_DOLLAR_ENDONLY(); |
583 |
|
Test_EXTENDED(); |
584 |
|
Test_NO_AUTO_CAPTURE(); |
585 |
|
Test_UNGREEDY(); |
586 |
|
Test_EXTRA(); |
587 |
|
Test_all_options(); |
588 |
|
} |
589 |
|
|
590 |
int main(int argc, char** argv) { |
int main(int argc, char** argv) { |
591 |
// Treat any flag as --help |
// Treat any flag as --help |
1030 |
TestRecursion(bytes, "ab.", matchlimit); |
TestRecursion(bytes, "ab.", matchlimit); |
1031 |
TestRecursion(bytes, "abc.", matchlimit); |
TestRecursion(bytes, "abc.", matchlimit); |
1032 |
|
|
1033 |
|
// Test Options |
1034 |
|
if (getenv("VERBOSE_TEST") != NULL) |
1035 |
|
VERBOSE_TEST = true; |
1036 |
|
TestOptions(); |
1037 |
|
|
1038 |
// Done |
// Done |
1039 |
printf("OK\n"); |
printf("OK\n"); |
1040 |
|
|