The tests all run clean with JIT.

This commit is contained in:
Philip.Hazel 2014-10-11 15:56:25 +00:00
parent 1ebad64b34
commit b6e793f343
6 changed files with 351 additions and 177 deletions

View File

@ -1,4 +1,4 @@
.TH PCRE2TEST 1 "10 October 2014" "PCRE 10.00" .TH PCRE2TEST 1 "11 October 2014" "PCRE 10.00"
.SH NAME .SH NAME
pcre2test - a program for testing Perl-compatible regular expressions. pcre2test - a program for testing Perl-compatible regular expressions.
.SH SYNOPSIS .SH SYNOPSIS
@ -433,6 +433,7 @@ about the pattern:
/I info show info about compiled pattern /I info show info about compiled pattern
hex pattern is coded in hexadecimal hex pattern is coded in hexadecimal
jit[=<number>] use JIT jit[=<number>] use JIT
jitverify verify JIT use
locale=<name> use this locale locale=<name> use this locale
memory show memory used memory show memory used
newline=<type> set newline type newline=<type> set newline type
@ -505,30 +506,33 @@ length of the pattern is passed. This is implied if \fBhex\fP is set.
.SS "JIT compilation" .SS "JIT compilation"
.rs .rs
.sp .sp
The \fB/jit\fP modifier may optionally be followed by a number in the range 0 The \fB/jit\fP modifier may optionally be followed by and equals sign and a
to 7: number in the range 0 to 7:
.sp .sp
0 disable JIT 0 disable JIT
1 normal match only 1 use JIT for normal match only
2 soft partial match only 2 use JIT for soft partial match only
3 normal match and soft partial match 3 use JIT for normal match and soft partial match
4 hard partial match only 4 use JIT for hard partial match only
6 soft and hard partial match 6 use JIT for soft and hard partial match
7 all three modes 7 all three modes
.sp .sp
If no number is given, 7 is assumed. If JIT compilation is successful, the 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, 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 for the appropriate type of match, except when incompatible run-time options
the are specified. For more details, see the
.\" HREF .\" HREF
\fBpcre2jit\fP \fBpcre2jit\fP
.\" .\"
documentation. See also the \fBjitstack\fP modifier below for a way of documentation. See also the \fBjitstack\fP modifier below for a way of
setting the size of the JIT stack. setting the size of the JIT stack.
.P .P
If the \fBjitverify\fP modifier is specified, the text "(JIT)" is added to the If the \fBjitverify\fP modifier is specified, information about the compiled
first output line after a match or non match when JIT-compiled code was pattern shows whether JIT compilation was or was not successful. If
actually used. This modifier can also be set on a subject line. \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" .SS "Setting a locale"
@ -632,7 +636,6 @@ not affect the compilation process.
allcaptures show all captures allcaptures show all captures
allusedtext show all consulted text allusedtext show all consulted text
/g global global matching /g global global matching
jitverify verify JIT usage
mark show mark values mark show mark values
.sp .sp
These modifiers may not appear in a \fB#pattern\fP command. If you want them as 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 getall extract all captured substrings
/g global global matching /g global global matching
jitstack=<n> set size of JIT stack jitstack=<n> set size of JIT stack
jitverify verify JIT usage
mark show mark values mark show mark values
match_limit=>n> set a match limit match_limit=>n> set a match limit
memory show memory usage 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 until it finds the minimum values for each parameter that allow
\fBpcre2_match()\fP to complete without error. \fBpcre2_match()\fP to complete without error.
.P .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 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 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 simple matches, the number is quite small, but for patterns with very large
@ -1153,6 +1159,6 @@ Cambridge CB2 3QH, England.
.rs .rs
.sp .sp
.nf .nf
Last updated: 10 October 2014 Last updated: 11 October 2014
Copyright (c) 1997-2014 University of Cambridge. Copyright (c) 1997-2014 University of Cambridge.
.fi .fi

View File

@ -448,7 +448,7 @@ static modstruct modlist[] = {
{ "info", MOD_PAT, MOD_CTL, CTL_INFO, PO(control) }, { "info", MOD_PAT, MOD_CTL, CTL_INFO, PO(control) },
{ "jit", MOD_PAT, MOD_IND, 7, PO(jit) }, { "jit", MOD_PAT, MOD_IND, 7, PO(jit) },
{ "jitstack", MOD_DAT, MOD_INT, 0, DO(jitstack) }, { "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) }, { "locale", MOD_PAT, MOD_STR, 0, PO(locale) },
{ "mark", MOD_PNDP, MOD_CTL, CTL_MARK, PO(control) }, { "mark", MOD_PNDP, MOD_CTL, CTL_MARK, PO(control) },
{ "match_limit", MOD_CTM, MOD_INT, 0, MO(match_limit) }, { "match_limit", MOD_CTM, MOD_INT, 0, MO(match_limit) },
@ -2709,7 +2709,7 @@ for (;;)
/* These on/off types have no data. */ /* 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); fprintf(outfile, "** Unrecognized modifier '%.*s'\n", (int)(ep-p), p);
return FALSE; return FALSE;
@ -2855,7 +2855,7 @@ for (;;)
break; 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); fprintf(outfile, "** Comma expected after modifier item '%s'\n", m->name);
return FALSE; return FALSE;
@ -3328,14 +3328,9 @@ if ((pat_patctl.control & CTL_INFO) != 0)
fprintf(outfile, "Subject length lower bound = %d\n", minlength); fprintf(outfile, "Subject length lower bound = %d\n", minlength);
/* FIXME: tidy this up */
if (pat_patctl.jit != 0 && (pat_patctl.control & CTL_JITVERIFY) != 0) if (pat_patctl.jit != 0 && (pat_patctl.control & CTL_JITVERIFY) != 0)
{ {
size_t jitsize; if (FLD(compiled_code, executable_jit) != NULL)
if (pattern_info(PCRE2_INFO_JITSIZE, &jitsize, FALSE) == 0)
{
if (jitsize > 0)
fprintf(outfile, "JIT compilation was successful\n"); fprintf(outfile, "JIT compilation was successful\n");
else else
#ifdef SUPPORT_JIT #ifdef SUPPORT_JIT
@ -3345,7 +3340,6 @@ if ((pat_patctl.control & CTL_INFO) != 0)
#endif #endif
} }
} }
}
return PR_OK; return PR_OK;
} }
@ -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])) else if (strncmp((char *)buffer, "#pattern", 8) == 0 && isspace(buffer[8]))
{ {
(void)decode_modifiers(buffer + 8, CTX_DEFPAT, &def_patctl, NULL); (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])) 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. */ /* Look for modifiers and options after the final delimiter. */
if (!decode_modifiers(p, CTX_PAT, &pat_patctl, NULL)) return PR_SKIP; 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; utf = (pat_patctl.options & PCRE2_UTF) != 0;
/* Now copy the pattern to pbuffer8 for use in 8-bit testing and for reflecting /* 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; 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) FLD(compiled_code, executable_jit) != NULL)
{ {
fprintf(outfile, "** Showing all consulted text is not supported by JIT: ignored\n"); 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 /* 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 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); PCRE2_JIT_STACK_ASSIGN(compiled_code, jit_callback, NULL);
} }
@ -4502,12 +4504,14 @@ for (gmatched = 0;; gmatched++)
(double)CLOCKS_PER_SEC); (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) 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_MATCHLIMIT, "match");
capcount = check_match_limit(pp, ulen, PCRE2_ERROR_RECURSIONLIMIT, if (FLD(compiled_code, executable_jit) == NULL)
(void)check_match_limit(pp, ulen, PCRE2_ERROR_RECURSIONLIMIT,
"recursion"); "recursion");
} }
@ -4565,9 +4569,6 @@ for (gmatched = 0;; gmatched++)
{ {
int i; int i;
uint8_t *nptr; 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. */ /* This is a check against a lunatic return value. */
@ -4635,13 +4636,27 @@ for (gmatched = 0;; gmatched++)
continue; continue;
} }
/* For the whole matched string, if ALLUSEDTEXT is set, and if the /* When JIT is not being used, ALLUSEDTEXT may be set. (It if is set with
leftmost consulted character is before the start of the match or the JIT, it is disabled above, with a comment.) When the match is done by the
rightmost consulted character is past the end of the match, we want to interpreter, leftchar and rightchar are available, and if ALLUSEDTEXT is
show all consulted characters, and indicate which were lookarounds. */ 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)
{
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;
showallused = i == 0 && (dat_datctl.control & CTL_ALLUSEDTEXT) != 0 &&
(leftchar < start || rightchar > end);
if (showallused) if (showallused)
{ {
PCHARS(lleft, pp, leftchar, start - leftchar, utf, outfile); PCHARS(lleft, pp, leftchar, start - leftchar, utf, outfile);
@ -4655,17 +4670,25 @@ for (gmatched = 0;; gmatched++)
if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used) if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)
fprintf(outfile, " (JIT)"); fprintf(outfile, " (JIT)");
fprintf(outfile, "\n");
if (showallused) if (showallused)
{ {
PCRE2_SIZE j; PCRE2_SIZE j;
fprintf(outfile, " "); fprintf(outfile, "\n ");
for (j = 0; j < lleft; j++) fprintf(outfile, "<"); for (j = 0; j < lleft; j++) fprintf(outfile, "<");
for (j = 0; j < lmiddle; j++) fprintf(outfile, " "); for (j = 0; j < lmiddle; j++) fprintf(outfile, " ");
for (j = 0; j < lright; j++) fprintf(outfile, ">"); for (j = 0; j < lright; j++) fprintf(outfile, ">");
fprintf(outfile, "\n");
} }
}
/* Not the main matched string. Just show it unadorned. */
else
{
PCHARSV(pp, start, end - start, utf, outfile);
}
fprintf(outfile, "\n");
/* Note: don't use the start/end variables here because we want to /* Note: don't use the start/end variables here because we want to
show the text from what is reported as the end. */ show the text from what is reported as the end. */
@ -4851,25 +4874,20 @@ for (gmatched = 0;; gmatched++)
} }
} /* End of handling a successful match */ } /* End of handling a successful match */
/* There was a partial match. If the bumpalong point is not the same as /* There was a partial match. The value of ovector[0] is the bumpalong point,
the first inspected character, show the offset explicitly. */ not any \K point that might exist. */
else if (capcount == PCRE2_ERROR_PARTIAL) else if (capcount == PCRE2_ERROR_PARTIAL)
{ {
PCRE2_SIZE leftchar = FLD(match_data, leftchar);
fprintf(outfile, "Partial match"); 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 && if ((dat_datctl.control & CTL_MARK) != 0 &&
TESTFLD(match_data, mark, !=, NULL)) TESTFLD(match_data, mark, !=, NULL))
{ {
fprintf(outfile, ", mark="); fprintf(outfile, ", mark=");
PCHARSV(CASTFLD(void *, match_data, mark), 0, -1, utf, outfile); PCHARSV(CASTFLD(void *, match_data, mark), 0, -1, utf, outfile);
} }
fprintf(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) if ((pat_patctl.control & CTL_JITVERIFY) != 0 && jit_was_used)
fprintf(outfile, " (JIT)"); fprintf(outfile, " (JIT)");
fprintf(outfile, "\n"); fprintf(outfile, "\n");

88
testdata/testinput16 vendored
View File

@ -1,23 +1,18 @@
# This test is run only when JIT support is available. It checks for a # This test is run only when JIT support is available. It checks JIT complete
# successful and an unsuccessful JIT compile, and a couple of things that are # and partial modes, and things that are different with JIT.
# 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 /(?(?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 aaaabcde
# Test various compile modes /abcd/I
#pattern jit,jitverify
/abcd/
abcd abcd
xyz xyz
@ -27,12 +22,6 @@
ab\=ph ab\=ph
xyz xyz
/abcd/
abcd
ab\=ps
ab\=ph
xyz
/abcd/jit=1 /abcd/jit=1
abcd abcd
ab\=ps ab\=ps
@ -84,4 +73,65 @@
/^12345678abcd/m /^12345678abcd/m
12345678abcd 12345678abcd
# End of testinput15 # Limits tests that give different output with JIT.
/(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

240
testdata/testoutput16 vendored
View File

@ -1,52 +1,28 @@
# This test is run only when JIT support is available. It checks for a # This test is run only when JIT support is available. It checks JIT complete
# successful and an unsuccessful JIT compile, and a couple of things that are # and partial modes, and things that are different with JIT.
# different with JIT.
/abc/I,jit #pattern jitverify
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
/(?(?C1)(?=a)a)/I,jit # JIT does not support this pattern (callout at start of condition).
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
/(?(?C1)(?=a)a)/I /(?(?C1)(?=a)a)/I
Capturing subpattern count = 0 Capturing subpattern count = 0
May match empty string May match empty string
No options Subject length lower bound = 0
No first code unit JIT compilation was not successful
No last code unit
Subject length lower bound = -1
No starting char list
JIT study was not successful
/a*/I # Check that an infinite recursion loop is caught.
Capturing subpattern count = 0
May match empty string
No options
No first code unit
No last code unit
Study returned NULL
/(?(R)a*(?1)|((?R))b)/S+ /(?(R)a*(?1)|((?R))b)/
aaaabcde aaaabcde
Error -27 (JIT stack limit reached) Failed: error -44: JIT stack limit reached
# Test various compile modes /abcd/I
Capturing subpattern count = 0
#pattern jit,jitverify First code unit = 'a'
Last code unit = 'd'
/abcd/ Subject length lower bound = 4
JIT compilation was successful
abcd abcd
0: abcd (JIT) 0: abcd (JIT)
xyz xyz
@ -55,19 +31,9 @@ No match (JIT)
/abcd/ /abcd/
abcd abcd
0: abcd (JIT) 0: abcd (JIT)
ab\P ab\=ps
Partial match: ab (JIT) Partial match: ab (JIT)
ab\P\P ab\=ph
Partial match: ab (JIT)
xyz
No match (JIT)
/abcd/
abcd
0: abcd (JIT)
ab\P
Partial match: ab (JIT)
ab\P\P
Partial match: ab (JIT) Partial match: ab (JIT)
xyz xyz
No match (JIT) No match (JIT)
@ -75,21 +41,21 @@ No match (JIT)
/abcd/jit=1 /abcd/jit=1
abcd abcd
0: abcd (JIT) 0: abcd (JIT)
ab\P ab\=ps
Partial match: ab Partial match: ab
ab\P\P ab\=ph
Partial match: ab Partial match: ab
xyz xyz
No match (JIT) No match (JIT)
xyz\P xyz\=ps
No match No match
/abcd/jit=2 /abcd/jit=2
abcd abcd
0: abcd 0: abcd
ab\P ab\=ps
Partial match: ab (JIT) Partial match: ab (JIT)
ab\P\P ab\=ph
Partial match: ab Partial match: ab
xyz xyz
No match No match
@ -97,9 +63,9 @@ No match
/abcd/jit=3 /abcd/jit=3
abcd abcd
0: abcd (JIT) 0: abcd (JIT)
ab\P ab\=ps
Partial match: ab (JIT) Partial match: ab (JIT)
ab\P\P ab\=ph
Partial match: ab Partial match: ab
xyz xyz
No match (JIT) No match (JIT)
@ -107,9 +73,9 @@ No match (JIT)
/abcd/jit=4 /abcd/jit=4
abcd abcd
0: abcd 0: abcd
ab\P ab\=ps
Partial match: ab Partial match: ab
ab\P\P ab\=ph
Partial match: ab (JIT) Partial match: ab (JIT)
xyz xyz
No match No match
@ -117,9 +83,9 @@ No match
/abcd/jit=5 /abcd/jit=5
abcd abcd
0: abcd (JIT) 0: abcd (JIT)
ab\P ab\=ps
Partial match: ab Partial match: ab
ab\P\P ab\=ph
Partial match: ab (JIT) Partial match: ab (JIT)
xyz xyz
No match (JIT) No match (JIT)
@ -127,9 +93,9 @@ No match (JIT)
/abcd/jit=6 /abcd/jit=6
abcd abcd
0: abcd 0: abcd
ab\P ab\=ps
Partial match: ab (JIT) Partial match: ab (JIT)
ab\P\P ab\=ph
Partial match: ab (JIT) Partial match: ab (JIT)
xyz xyz
No match No match
@ -137,21 +103,19 @@ No match
/abcd/jit=7 /abcd/jit=7
abcd abcd
0: abcd (JIT) 0: abcd (JIT)
ab\P ab\=ps
Partial match: ab (JIT) Partial match: ab (JIT)
ab\P\P ab\=ph
Partial match: ab (JIT) Partial match: ab (JIT)
xyz xyz
No match (JIT) No match (JIT)
/abcd/I,jit=2 /abcd/I,jit=2
Capturing subpattern count = 0 Capturing subpattern count = 0
No options
First code unit = 'a' First code unit = 'a'
Last code unit = 'd' Last code unit = 'd'
Subject length lower bound = 4 Subject length lower bound = 4
No starting char list JIT compilation was successful
JIT study was successful
/(*NO_START_OPT)a(*:m)b/mark /(*NO_START_OPT)a(*:m)b/mark
a a
@ -161,4 +125,140 @@ No match, mark = m (JIT)
12345678abcd 12345678abcd
0: 12345678abcd (JIT) 0: 12345678abcd (JIT)
# End of testinput15 # Limits tests that give different output with JIT.
/(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

14
testdata/testoutput2 vendored
View File

@ -9286,17 +9286,17 @@ Partial match: abc12
xyzabc123pqr xyzabc123pqr
0: 123 0: 123
xyzabc12\=ps xyzabc12\=ps
Partial match at offset 6: abc12 Partial match: 12
xyzabc12\=ph xyzabc12\=ph
Partial match at offset 6: abc12 Partial match: 12
/\babc\b/ /\babc\b/
+++abc+++ +++abc+++
0: abc 0: abc
+++ab\=ps +++ab\=ps
Partial match at offset 3: +ab Partial match: ab
+++ab\=ph +++ab\=ph
Partial match at offset 3: +ab Partial match: ab
/(?&word)(?&element)(?(DEFINE)(?<element><[^m][^>]>[^<])(?<word>\w*+))/B /(?&word)(?&element)(?(DEFINE)(?<element><[^m][^>]>[^<])(?<word>\w*+))/B
------------------------------------------------------------------ ------------------------------------------------------------------
@ -10324,7 +10324,7 @@ No match
/(?<=abc)def/ /(?<=abc)def/
abc\=ph abc\=ph
Partial match at offset 3: abc Partial match:
/abc$/ /abc$/
abc abc
@ -11877,9 +11877,9 @@ Callout 2: last capture = 0
/(?<=123)(*MARK:xx)abc/mark /(?<=123)(*MARK:xx)abc/mark
xxxx123a\=ph xxxx123a\=ph
Partial match at offset 7, mark=xx: 123a Partial match, mark=xx: a
xxxx123a\=ps xxxx123a\=ps
Partial match at offset 7, mark=xx: 123a Partial match, mark=xx: a
/123\Kabc/ /123\Kabc/
xxxx123a\=ph xxxx123a\=ph

12
testdata/testoutput6 vendored
View File

@ -947,7 +947,7 @@ Partial match: abc
xyzfo\=ps xyzfo\=ps
No match No match
foob\=ps,offset=2 foob\=ps,offset=2
Partial match at offset 3: foob Partial match: b
foobar...\=ps,dfa_restart,offset=4 foobar...\=ps,dfa_restart,offset=4
0: ar 0: ar
xyzfo\=ps xyzfo\=ps
@ -7092,17 +7092,17 @@ Failed: error -40: item unsupported for DFA matching
xyzabc123pqr xyzabc123pqr
0: 123 0: 123
xyzabc12\=ps xyzabc12\=ps
Partial match at offset 6: abc12 Partial match: 12
xyzabc12\=ph xyzabc12\=ph
Partial match at offset 6: abc12 Partial match: 12
/\babc\b/ /\babc\b/
+++abc+++ +++abc+++
0: abc 0: abc
+++ab\=ps +++ab\=ps
Partial match at offset 3: +ab Partial match: ab
+++ab\=ph +++ab\=ph
Partial match at offset 3: +ab Partial match: ab
/(?=C)/g,aftertext /(?=C)/g,aftertext
ABCDECBA ABCDECBA
@ -7226,7 +7226,7 @@ Failed: error -40: item unsupported for DFA matching
/(?<=abc)def/ /(?<=abc)def/
abc\=ph abc\=ph
Partial match at offset 3: abc Partial match:
/abc$/ /abc$/
abc abc