From b6e793f34338a97ebecf99364ce585b40f81fa85 Mon Sep 17 00:00:00 2001 From: "Philip.Hazel" Date: Sat, 11 Oct 2014 15:56:25 +0000 Subject: [PATCH] The tests all run clean with JIT. --- doc/pcre2test.1 | 40 ++++--- src/pcre2test.c | 134 +++++++++++++---------- testdata/testinput16 | 88 ++++++++++++---- testdata/testoutput16 | 240 ++++++++++++++++++++++++++++++------------ testdata/testoutput2 | 14 +-- testdata/testoutput6 | 12 +-- 6 files changed, 351 insertions(+), 177 deletions(-) diff --git a/doc/pcre2test.1 b/doc/pcre2test.1 index 445eaab..fd782b6 100644 --- a/doc/pcre2test.1 +++ b/doc/pcre2test.1 @@ -1,4 +1,4 @@ -.TH PCRE2TEST 1 "10 October 2014" "PCRE 10.00" +.TH PCRE2TEST 1 "11 October 2014" "PCRE 10.00" .SH NAME pcre2test - a program for testing Perl-compatible regular expressions. .SH SYNOPSIS @@ -433,6 +433,7 @@ about the pattern: /I info show info about compiled pattern hex pattern is coded in hexadecimal jit[=] use JIT + jitverify verify JIT use locale= use this locale memory show memory used newline= set newline type @@ -505,30 +506,33 @@ length of the pattern is passed. This is implied if \fBhex\fP is set. .SS "JIT compilation" .rs .sp -The \fB/jit\fP modifier may optionally be followed by a number in the range 0 -to 7: +The \fB/jit\fP modifier may optionally be followed by and equals sign and a +number in the range 0 to 7: .sp 0 disable JIT - 1 normal match only - 2 soft partial match only - 3 normal match and soft partial match - 4 hard partial match only - 6 soft and hard partial match + 1 use JIT for normal match only + 2 use JIT for soft partial match only + 3 use JIT for normal match and soft partial match + 4 use JIT for hard partial match only + 6 use JIT for soft and hard partial match 7 all three modes .sp If no number is given, 7 is assumed. If JIT compilation is successful, the -compiled JIT code will automatically be used when \fBpcre2_match()\fP is run, -except when incompatible run-time options are specified. For more details, see -the +compiled JIT code will automatically be used when \fBpcre2_match()\fP is run +for the appropriate type of match, except when incompatible run-time options +are specified. For more details, see the .\" HREF \fBpcre2jit\fP .\" documentation. See also the \fBjitstack\fP modifier below for a way of setting the size of the JIT stack. .P -If the \fBjitverify\fP modifier is specified, the text "(JIT)" is added to the -first output line after a match or non match when JIT-compiled code was -actually used. This modifier can also be set on a subject line. +If the \fBjitverify\fP modifier is specified, information about the compiled +pattern shows whether JIT compilation was or was not successful. If +\fBjitverify\fP is specified without \fBjit\fP, jit=7 is assumed. If JIT +compilation is successful when \fBjitverify\fP is set, the text "(JIT)" is +added to the first output line after a match or non match when JIT-compiled +code was actually used. . . .SS "Setting a locale" @@ -632,7 +636,6 @@ not affect the compilation process. allcaptures show all captures allusedtext show all consulted text /g global global matching - jitverify verify JIT usage mark show mark values .sp These modifiers may not appear in a \fB#pattern\fP command. If you want them as @@ -701,7 +704,6 @@ pattern. getall extract all captured substrings /g global global matching jitstack= set size of JIT stack - jitverify verify JIT usage mark show mark values match_limit=>n> set a match limit memory show memory usage @@ -842,6 +844,10 @@ context via \fBpcre2_set_match_limit()\fP and \fBpcre2_set_recursion_limit()\fP until it finds the minimum values for each parameter that allow \fBpcre2_match()\fP to complete without error. .P +If JIT is being used, only the match limit is relevant. If DFA matching is +being used, neither limit is relevant, and this modifier is ignored (with a +warning message). +.P The \fImatch_limit\fP number is a measure of the amount of backtracking that takes place, and learning the minimum value can be instructive. For most simple matches, the number is quite small, but for patterns with very large @@ -1153,6 +1159,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 10 October 2014 +Last updated: 11 October 2014 Copyright (c) 1997-2014 University of Cambridge. .fi diff --git a/src/pcre2test.c b/src/pcre2test.c index 20cd57b..97b6de3 100644 --- a/src/pcre2test.c +++ b/src/pcre2test.c @@ -448,7 +448,7 @@ static modstruct modlist[] = { { "info", MOD_PAT, MOD_CTL, CTL_INFO, PO(control) }, { "jit", MOD_PAT, MOD_IND, 7, PO(jit) }, { "jitstack", MOD_DAT, MOD_INT, 0, DO(jitstack) }, - { "jitverify", MOD_PND, MOD_CTL, CTL_JITVERIFY, PO(control) }, + { "jitverify", MOD_PAT, MOD_CTL, CTL_JITVERIFY, PO(control) }, { "locale", MOD_PAT, MOD_STR, 0, PO(locale) }, { "mark", MOD_PNDP, MOD_CTL, CTL_MARK, PO(control) }, { "match_limit", MOD_CTM, MOD_INT, 0, MO(match_limit) }, @@ -2632,7 +2632,7 @@ for (;;) pp = p; while (pp < ep && *pp != '=') pp++; index = scan_modifiers(p, pp - p); - + /* If the first modifier is unrecognized, try to interpret it as a sequence of single-character abbreviated modifiers. None of these modifiers have any associated data. They just set options or control bits. */ @@ -2709,7 +2709,7 @@ for (;;) /* These on/off types have no data. */ - else if (*pp != ',' && *pp != '\n' && *pp != 0) + else if (*pp != ',' && *pp != '\n' && *pp != ' ' && *pp != 0) { fprintf(outfile, "** Unrecognized modifier '%.*s'\n", (int)(ep-p), p); return FALSE; @@ -2855,7 +2855,7 @@ for (;;) break; } - if (*pp != ',' && *pp != '\n' && *pp != 0) + if (*pp != ',' && *pp != '\n' && *pp != ' ' && *pp != 0) { fprintf(outfile, "** Comma expected after modifier item '%s'\n", m->name); return FALSE; @@ -3328,22 +3328,16 @@ if ((pat_patctl.control & CTL_INFO) != 0) fprintf(outfile, "Subject length lower bound = %d\n", minlength); -/* FIXME: tidy this up */ - if (pat_patctl.jit != 0 && (pat_patctl.control & CTL_JITVERIFY) != 0) { - size_t jitsize; - if (pattern_info(PCRE2_INFO_JITSIZE, &jitsize, FALSE) == 0) - { - if (jitsize > 0) - fprintf(outfile, "JIT compilation was successful\n"); - else + if (FLD(compiled_code, executable_jit) != NULL) + fprintf(outfile, "JIT compilation was successful\n"); + else #ifdef SUPPORT_JIT - fprintf(outfile, "JIT compilation was not successful\n"); + fprintf(outfile, "JIT compilation was not successful\n"); #else - fprintf(outfile, "JIT support is not available in this version of PCRE2\n"); + fprintf(outfile, "JIT support is not available in this version of PCRE2\n"); #endif - } } } @@ -3382,6 +3376,8 @@ if (strncmp((char *)buffer, "#forbid_utf", 11) == 0 && isspace(buffer[11])) else if (strncmp((char *)buffer, "#pattern", 8) == 0 && isspace(buffer[8])) { (void)decode_modifiers(buffer + 8, CTX_DEFPAT, &def_patctl, NULL); + if (def_patctl.jit == 0 && (def_patctl.control & CTL_JITVERIFY) != 0) + def_patctl.jit = 7; } else if (strncmp((char *)buffer, "#perltest", 9) == 0 && isspace(buffer[9])) { @@ -3467,6 +3463,9 @@ patlen = p - buffer - 2; /* Look for modifiers and options after the final delimiter. */ if (!decode_modifiers(p, CTX_PAT, &pat_patctl, NULL)) return PR_SKIP; + +if (pat_patctl.jit == 0 && (pat_patctl.control & CTL_JITVERIFY) != 0) + pat_patctl.jit = 7; utf = (pat_patctl.options & PCRE2_UTF) != 0; /* Now copy the pattern to pbuffer8 for use in 8-bit testing and for reflecting @@ -4385,7 +4384,10 @@ if ((dat_datctl.control & (CTL_DFA|CTL_FINDLIMITS)) == (CTL_DFA|CTL_FINDLIMITS)) dat_datctl.control &= ~CTL_FINDLIMITS; } -if ((dat_datctl.control & CTL_ALLUSEDTEXT) != 0 && +/* ALLUSEDTEXT is not supported with JIT, but JIT is not used with DFA +matching, even if the JIT compiler was used. */ + +if ((dat_datctl.control & (CTL_ALLUSEDTEXT|CTL_DFA)) == CTL_ALLUSEDTEXT && FLD(compiled_code, executable_jit) != NULL) { fprintf(outfile, "** Showing all consulted text is not supported by JIT: ignored\n"); @@ -4427,7 +4429,7 @@ else if (jit_stack != NULL) /* When no JIT stack is assigned, we must ensure that there is a JIT callback if we want to verify that JIT was actually used. */ -if ((dat_datctl.control & CTL_JITVERIFY) != 0 && jit_stack == NULL) +if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_stack == NULL) { PCRE2_JIT_STACK_ASSIGN(compiled_code, jit_callback, NULL); } @@ -4502,13 +4504,15 @@ for (gmatched = 0;; gmatched++) (double)CLOCKS_PER_SEC); } - /* Find the match and recursion limits if requested. */ + /* Find the match and recursion limits if requested. The recursion limit + is not relevant for JIT. */ if ((dat_datctl.control & CTL_FINDLIMITS) != 0) { - (void)check_match_limit(pp, ulen, PCRE2_ERROR_MATCHLIMIT, "match"); - capcount = check_match_limit(pp, ulen, PCRE2_ERROR_RECURSIONLIMIT, - "recursion"); + capcount = check_match_limit(pp, ulen, PCRE2_ERROR_MATCHLIMIT, "match"); + if (FLD(compiled_code, executable_jit) == NULL) + (void)check_match_limit(pp, ulen, PCRE2_ERROR_RECURSIONLIMIT, + "recursion"); } /* Otherwise just run a single match, setting up a callout if required (the @@ -4565,10 +4569,7 @@ for (gmatched = 0;; gmatched++) { int i; uint8_t *nptr; - BOOL showallused; - PCRE2_SIZE leftchar = FLD(match_data, leftchar); - PCRE2_SIZE rightchar = FLD(match_data, rightchar); - + /* This is a check against a lunatic return value. */ if (capcount > (int)dat_datctl.oveccount) @@ -4635,38 +4636,60 @@ for (gmatched = 0;; gmatched++) continue; } - /* For the whole matched string, if ALLUSEDTEXT is set, and if the - leftmost consulted character is before the start of the match or the - rightmost consulted character is past the end of the match, we want to - show all consulted characters, and indicate which were lookarounds. */ - - showallused = i == 0 && (dat_datctl.control & CTL_ALLUSEDTEXT) != 0 && - (leftchar < start || rightchar > end); - if (showallused) + /* When JIT is not being used, ALLUSEDTEXT may be set. (It if is set with + JIT, it is disabled above, with a comment.) When the match is done by the + interpreter, leftchar and rightchar are available, and if ALLUSEDTEXT is + set, and if the leftmost consulted character is before the start of the + match or the rightmost consulted character is past the end of the match, + we want to show all consulted characters for the main matched string, and + indicate which were lookarounds. */ + + if (i == 0) { - PCHARS(lleft, pp, leftchar, start - leftchar, utf, outfile); - PCHARS(lmiddle, pp, start, end - start, utf, outfile); - PCHARS(lright, pp, end, rightchar - end, utf, outfile); + BOOL showallused; + PCRE2_SIZE leftchar, rightchar; + + if ((dat_datctl.control & CTL_ALLUSEDTEXT) != 0) + { + leftchar = FLD(match_data, leftchar); + rightchar = FLD(match_data, rightchar); + showallused = i == 0 && (leftchar < start || rightchar > end); + } + else showallused = FALSE; + + if (showallused) + { + PCHARS(lleft, pp, leftchar, start - leftchar, utf, outfile); + PCHARS(lmiddle, pp, start, end - start, utf, outfile); + PCHARS(lright, pp, end, rightchar - end, utf, outfile); + } + else + { + PCHARSV(pp, start, end - start, utf, outfile); + } + + if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) + fprintf(outfile, " (JIT)"); + + if (showallused) + { + PCRE2_SIZE j; + fprintf(outfile, "\n "); + for (j = 0; j < lleft; j++) fprintf(outfile, "<"); + for (j = 0; j < lmiddle; j++) fprintf(outfile, " "); + for (j = 0; j < lright; j++) fprintf(outfile, ">"); + } } + + /* Not the main matched string. Just show it unadorned. */ + else { PCHARSV(pp, start, end - start, utf, outfile); } - - if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) - fprintf(outfile, " (JIT)"); + fprintf(outfile, "\n"); - - if (showallused) - { - PCRE2_SIZE j; - fprintf(outfile, " "); - for (j = 0; j < lleft; j++) fprintf(outfile, "<"); - for (j = 0; j < lmiddle; j++) fprintf(outfile, " "); - for (j = 0; j < lright; j++) fprintf(outfile, ">"); - fprintf(outfile, "\n"); - } - + /* Note: don't use the start/end variables here because we want to show the text from what is reported as the end. */ @@ -4851,25 +4874,20 @@ for (gmatched = 0;; gmatched++) } } /* End of handling a successful match */ - /* There was a partial match. If the bumpalong point is not the same as - the first inspected character, show the offset explicitly. */ + /* There was a partial match. The value of ovector[0] is the bumpalong point, + not any \K point that might exist. */ else if (capcount == PCRE2_ERROR_PARTIAL) { - PCRE2_SIZE leftchar = FLD(match_data, leftchar); fprintf(outfile, "Partial match"); - if (leftchar != FLD(match_data, startchar)) - fprintf(outfile, " at offset %d", (int)FLD(match_data, startchar)); - if ((dat_datctl.control & CTL_MARK) != 0 && TESTFLD(match_data, mark, !=, NULL)) { fprintf(outfile, ", mark="); PCHARSV(CASTFLD(void *, match_data, mark), 0, -1, utf, outfile); } - fprintf(outfile, ": "); - PCHARSV(pp, leftchar, ulen - leftchar, utf, outfile); + PCHARSV(pp, ovector[0], ulen - ovector[0], utf, outfile); if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) fprintf(outfile, " (JIT)"); fprintf(outfile, "\n"); diff --git a/testdata/testinput16 b/testdata/testinput16 index 47bbb11..b331b0a 100644 --- a/testdata/testinput16 +++ b/testdata/testinput16 @@ -1,23 +1,18 @@ -# This test is run only when JIT support is available. It checks for a -# successful and an unsuccessful JIT compile, and a couple of things that are -# different with JIT. +# This test is run only when JIT support is available. It checks JIT complete +# and partial modes, and things that are different with JIT. -/abc/I,jit +#pattern jitverify -/(?(?C1)(?=a)a)/I,jit +# JIT does not support this pattern (callout at start of condition). /(?(?C1)(?=a)a)/I -/a*/I +# Check that an infinite recursion loop is caught. -/(?(R)a*(?1)|((?R))b)/jit +/(?(R)a*(?1)|((?R))b)/ aaaabcde -# Test various compile modes - -#pattern jit,jitverify - -/abcd/ +/abcd/I abcd xyz @@ -27,12 +22,6 @@ ab\=ph xyz -/abcd/ - abcd - ab\=ps - ab\=ph - xyz - /abcd/jit=1 abcd ab\=ps @@ -83,5 +72,66 @@ /^12345678abcd/m 12345678abcd + +# Limits tests that give different output with JIT. -# End of testinput15 +/(a+)*zz/I + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\=find_limits + aaaaaaaaaaaaaz\=find_limits + +!((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)!I + /* this is a C style comment */\=find_limits + +/^(?>a)++/ + aa\=find_limits + aaaaaaaaa\=find_limits + +/(a)(?1)++/ + aa\=find_limits + aaaaaaaaa\=find_limits + +/a(?:.)*?a/ims + abbbbbbbbbbbbbbbbbbbbba\=find_limits + +/a(?:.(*THEN))*?a/ims + abbbbbbbbbbbbbbbbbbbbba\=find_limits + +/a(?:.(*THEN:ABC))*?a/ims + abbbbbbbbbbbbbbbbbbbbba\=find_limits + +/^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/ + aabbccddee\=find_limits + +/^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/ + aabbccddee\=find_limits + +/^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/ + aabbccddee\=find_limits + +/(a+)*zz/ + aaaaaaaaaaaaaz + aaaaaaaaaaaaaz\=match_limit=3000 + +/(*LIMIT_MATCH=3000)(a+)*zz/I + aaaaaaaaaaaaaz + aaaaaaaaaaaaaz\=match_limit=60000 + +/(*LIMIT_MATCH=60000)(*LIMIT_MATCH=3000)(a+)*zz/I + aaaaaaaaaaaaaz + +/(*LIMIT_MATCH=60000)(a+)*zz/I + aaaaaaaaaaaaaz + aaaaaaaaaaaaaz\=match_limit=3000 + +# These three have infinitely nested recursions. + +/((?2))((?1))/ + abc + +/((?(R2)a+|(?1)b))/ + aaaabcde + +/(?(R)a*(?1)|((?R))b)/ + aaaabcde + +# End of testinput16 diff --git a/testdata/testoutput16 b/testdata/testoutput16 index 630ae04..0c02742 100644 --- a/testdata/testoutput16 +++ b/testdata/testoutput16 @@ -1,52 +1,28 @@ -# This test is run only when JIT support is available. It checks for a -# successful and an unsuccessful JIT compile, and a couple of things that are -# different with JIT. +# This test is run only when JIT support is available. It checks JIT complete +# and partial modes, and things that are different with JIT. -/abc/I,jit -Capturing subpattern count = 0 -No options -First code unit = 'a' -Need char = 'c' -Subject length lower bound = 3 -No starting char list -JIT study was successful +#pattern jitverify -/(?(?C1)(?=a)a)/I,jit -Capturing subpattern count = 0 -May match empty string -No options -No first code unit -No last code unit -Study returned NULL -JIT study was not successful +# JIT does not support this pattern (callout at start of condition). /(?(?C1)(?=a)a)/I Capturing subpattern count = 0 May match empty string -No options -No first code unit -No last code unit -Subject length lower bound = -1 -No starting char list -JIT study was not successful +Subject length lower bound = 0 +JIT compilation was not successful -/a*/I -Capturing subpattern count = 0 -May match empty string -No options -No first code unit -No last code unit -Study returned NULL +# Check that an infinite recursion loop is caught. -/(?(R)a*(?1)|((?R))b)/S+ +/(?(R)a*(?1)|((?R))b)/ aaaabcde -Error -27 (JIT stack limit reached) +Failed: error -44: JIT stack limit reached -# Test various compile modes - -#pattern jit,jitverify - -/abcd/ +/abcd/I +Capturing subpattern count = 0 +First code unit = 'a' +Last code unit = 'd' +Subject length lower bound = 4 +JIT compilation was successful abcd 0: abcd (JIT) xyz @@ -55,19 +31,9 @@ No match (JIT) /abcd/ abcd 0: abcd (JIT) - ab\P + ab\=ps Partial match: ab (JIT) - ab\P\P -Partial match: ab (JIT) - xyz -No match (JIT) - -/abcd/ - abcd - 0: abcd (JIT) - ab\P -Partial match: ab (JIT) - ab\P\P + ab\=ph Partial match: ab (JIT) xyz No match (JIT) @@ -75,21 +41,21 @@ No match (JIT) /abcd/jit=1 abcd 0: abcd (JIT) - ab\P + ab\=ps Partial match: ab - ab\P\P + ab\=ph Partial match: ab xyz No match (JIT) - xyz\P + xyz\=ps No match /abcd/jit=2 abcd 0: abcd - ab\P + ab\=ps Partial match: ab (JIT) - ab\P\P + ab\=ph Partial match: ab xyz No match @@ -97,9 +63,9 @@ No match /abcd/jit=3 abcd 0: abcd (JIT) - ab\P + ab\=ps Partial match: ab (JIT) - ab\P\P + ab\=ph Partial match: ab xyz No match (JIT) @@ -107,9 +73,9 @@ No match (JIT) /abcd/jit=4 abcd 0: abcd - ab\P + ab\=ps Partial match: ab - ab\P\P + ab\=ph Partial match: ab (JIT) xyz No match @@ -117,9 +83,9 @@ No match /abcd/jit=5 abcd 0: abcd (JIT) - ab\P + ab\=ps Partial match: ab - ab\P\P + ab\=ph Partial match: ab (JIT) xyz No match (JIT) @@ -127,9 +93,9 @@ No match (JIT) /abcd/jit=6 abcd 0: abcd - ab\P + ab\=ps Partial match: ab (JIT) - ab\P\P + ab\=ph Partial match: ab (JIT) xyz No match @@ -137,21 +103,19 @@ No match /abcd/jit=7 abcd 0: abcd (JIT) - ab\P + ab\=ps Partial match: ab (JIT) - ab\P\P + ab\=ph Partial match: ab (JIT) xyz No match (JIT) /abcd/I,jit=2 Capturing subpattern count = 0 -No options First code unit = 'a' Last code unit = 'd' Subject length lower bound = 4 -No starting char list -JIT study was successful +JIT compilation was successful /(*NO_START_OPT)a(*:m)b/mark a @@ -160,5 +124,141 @@ No match, mark = m (JIT) /^12345678abcd/m 12345678abcd 0: 12345678abcd (JIT) + +# Limits tests that give different output with JIT. -# End of testinput15 +/(a+)*zz/I +Capturing subpattern count = 1 +Starting code units: a z +Last code unit = 'z' +Subject length lower bound = 2 +JIT compilation was successful + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\=find_limits +Minimum match limit = 3 + 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazz (JIT) + 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaz\=find_limits +Minimum match limit = 16384 +No match (JIT) + +!((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)!I +Capturing subpattern count = 1 +May match empty string +Subject length lower bound = 0 +JIT compilation was successful + /* this is a C style comment */\=find_limits +Minimum match limit = 2 + 0: /* this is a C style comment */ (JIT) + 1: /* this is a C style comment */ + +/^(?>a)++/ + aa\=find_limits +Minimum match limit = 2 + 0: aa (JIT) + aaaaaaaaa\=find_limits +Minimum match limit = 2 + 0: aaaaaaaaa (JIT) + +/(a)(?1)++/ + aa\=find_limits +Minimum match limit = 2 + 0: aa (JIT) + 1: a + aaaaaaaaa\=find_limits +Minimum match limit = 2 + 0: aaaaaaaaa (JIT) + 1: a + +/a(?:.)*?a/ims + abbbbbbbbbbbbbbbbbbbbba\=find_limits +Minimum match limit = 1 + 0: abbbbbbbbbbbbbbbbbbbbba (JIT) + +/a(?:.(*THEN))*?a/ims + abbbbbbbbbbbbbbbbbbbbba\=find_limits +Minimum match limit = 1 + 0: abbbbbbbbbbbbbbbbbbbbba (JIT) + +/a(?:.(*THEN:ABC))*?a/ims + abbbbbbbbbbbbbbbbbbbbba\=find_limits +Minimum match limit = 1 + 0: abbbbbbbbbbbbbbbbbbbbba (JIT) + +/^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/ + aabbccddee\=find_limits +Minimum match limit = 6 + 0: aabbccddee (JIT) + +/^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/ + aabbccddee\=find_limits +Minimum match limit = 6 + 0: aabbccddee (JIT) + 1: aa + 2: bb + 3: cc + 4: dd + 5: ee + +/^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/ + aabbccddee\=find_limits +Minimum match limit = 6 + 0: aabbccddee (JIT) + 1: aa + 2: cc + 3: ee + +/(a+)*zz/ + aaaaaaaaaaaaaz +No match (JIT) + aaaaaaaaaaaaaz\=match_limit=3000 +Failed: error -45: match limit exceeded + +/(*LIMIT_MATCH=3000)(a+)*zz/I +Capturing subpattern count = 1 +Match limit = 3000 +Starting code units: a z +Last code unit = 'z' +Subject length lower bound = 2 +JIT compilation was successful + aaaaaaaaaaaaaz +Failed: error -45: match limit exceeded + aaaaaaaaaaaaaz\=match_limit=60000 +Failed: error -45: match limit exceeded + +/(*LIMIT_MATCH=60000)(*LIMIT_MATCH=3000)(a+)*zz/I +Capturing subpattern count = 1 +Match limit = 3000 +Starting code units: a z +Last code unit = 'z' +Subject length lower bound = 2 +JIT compilation was successful + aaaaaaaaaaaaaz +Failed: error -45: match limit exceeded + +/(*LIMIT_MATCH=60000)(a+)*zz/I +Capturing subpattern count = 1 +Match limit = 60000 +Starting code units: a z +Last code unit = 'z' +Subject length lower bound = 2 +JIT compilation was successful + aaaaaaaaaaaaaz +No match (JIT) + aaaaaaaaaaaaaz\=match_limit=3000 +Failed: error -45: match limit exceeded + +# These three have infinitely nested recursions. + +/((?2))((?1))/ + abc +Failed: error -44: JIT stack limit reached + +/((?(R2)a+|(?1)b))/ + aaaabcde +Failed: error -44: JIT stack limit reached + +/(?(R)a*(?1)|((?R))b)/ + aaaabcde +Failed: error -44: JIT stack limit reached + +# End of testinput16 diff --git a/testdata/testoutput2 b/testdata/testoutput2 index 09c8a74..a8a4df6 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -9286,17 +9286,17 @@ Partial match: abc12 xyzabc123pqr 0: 123 xyzabc12\=ps -Partial match at offset 6: abc12 +Partial match: 12 xyzabc12\=ph -Partial match at offset 6: abc12 +Partial match: 12 /\babc\b/ +++abc+++ 0: abc +++ab\=ps -Partial match at offset 3: +ab +Partial match: ab +++ab\=ph -Partial match at offset 3: +ab +Partial match: ab /(?&word)(?&element)(?(DEFINE)(?<[^m][^>]>[^<])(?\w*+))/B ------------------------------------------------------------------ @@ -10324,7 +10324,7 @@ No match /(?<=abc)def/ abc\=ph -Partial match at offset 3: abc +Partial match: /abc$/ abc @@ -11877,9 +11877,9 @@ Callout 2: last capture = 0 /(?<=123)(*MARK:xx)abc/mark xxxx123a\=ph -Partial match at offset 7, mark=xx: 123a +Partial match, mark=xx: a xxxx123a\=ps -Partial match at offset 7, mark=xx: 123a +Partial match, mark=xx: a /123\Kabc/ xxxx123a\=ph diff --git a/testdata/testoutput6 b/testdata/testoutput6 index 40e8a93..c629985 100644 --- a/testdata/testoutput6 +++ b/testdata/testoutput6 @@ -947,7 +947,7 @@ Partial match: abc xyzfo\=ps No match foob\=ps,offset=2 -Partial match at offset 3: foob +Partial match: b foobar...\=ps,dfa_restart,offset=4 0: ar xyzfo\=ps @@ -7092,17 +7092,17 @@ Failed: error -40: item unsupported for DFA matching xyzabc123pqr 0: 123 xyzabc12\=ps -Partial match at offset 6: abc12 +Partial match: 12 xyzabc12\=ph -Partial match at offset 6: abc12 +Partial match: 12 /\babc\b/ +++abc+++ 0: abc +++ab\=ps -Partial match at offset 3: +ab +Partial match: ab +++ab\=ph -Partial match at offset 3: +ab +Partial match: ab /(?=C)/g,aftertext ABCDECBA @@ -7226,7 +7226,7 @@ Failed: error -40: item unsupported for DFA matching /(?<=abc)def/ abc\=ph -Partial match at offset 3: abc +Partial match: /abc$/ abc