Code for pcre2_substitute(), and tests.
This commit is contained in:
parent
1bbc86fe67
commit
f1c6ee730a
|
@ -1,4 +1,4 @@
|
||||||
.TH PCRE2TEST 1 "02 November 2014" "PCRE 10.00"
|
.TH PCRE2TEST 1 "09 November 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
|
||||||
|
@ -447,7 +447,6 @@ about the pattern:
|
||||||
posix use the POSIX API
|
posix use the POSIX API
|
||||||
stackguard=<number> test the stackguard feature
|
stackguard=<number> test the stackguard feature
|
||||||
tables=[0|1|2] select internal tables
|
tables=[0|1|2] select internal tables
|
||||||
use_length use the pattern's length
|
|
||||||
.sp
|
.sp
|
||||||
The effects of these modifiers are described in the following sections.
|
The effects of these modifiers are described in the following sections.
|
||||||
FIXME: Give more examples.
|
FIXME: Give more examples.
|
||||||
|
@ -497,15 +496,10 @@ pairs. For example:
|
||||||
/ab 32 59/hex
|
/ab 32 59/hex
|
||||||
.sp
|
.sp
|
||||||
This feature is provided as a way of creating patterns that contain binary zero
|
This feature is provided as a way of creating patterns that contain binary zero
|
||||||
characters. When \fBhex\fP is set, it implies \fBuse_length\fP.
|
characters. By default, \fBpcre2test\fP passes patterns as zero-terminated
|
||||||
.
|
strings to \fBpcre2_compile()\fP, giving the length as PCRE2_ZERO_TERMINATED.
|
||||||
.
|
However, for patterns specified in hexadecimal, the length of the pattern is
|
||||||
.SS "Using the pattern's length"
|
passed.
|
||||||
.rs
|
|
||||||
.sp
|
|
||||||
By default, \fBpcre2test\fP passes patterns as zero-terminated strings to
|
|
||||||
\fBpcre2_compile()\fP, giving the length as -1. If \fBuse_length\fP is set, the
|
|
||||||
length of the pattern is passed. This is implied if \fBhex\fP is set.
|
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
.SS "JIT compilation"
|
.SS "JIT compilation"
|
||||||
|
@ -726,6 +720,7 @@ pattern.
|
||||||
ovector=<n> set size of output vector
|
ovector=<n> set size of output vector
|
||||||
recursion_limit=<n> set a recursion limit
|
recursion_limit=<n> set a recursion limit
|
||||||
startchar show startchar when relevant
|
startchar show startchar when relevant
|
||||||
|
zero_terminate pass the subject as zero-terminated
|
||||||
.sp
|
.sp
|
||||||
The effects of these modifiers are described in the following sections.
|
The effects of these modifiers are described in the following sections.
|
||||||
FIXME: Give more examples.
|
FIXME: Give more examples.
|
||||||
|
@ -931,6 +926,19 @@ create a match block with a zero-length ovector; there is always one pair of
|
||||||
offsets.)
|
offsets.)
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
|
.SS "Passing the subject as zero-terminated"
|
||||||
|
.rs
|
||||||
|
.sp
|
||||||
|
By default, the subject string is passed to a native API matching function with
|
||||||
|
its correct length. In order to test the facility for passing a zero-terminated
|
||||||
|
string, the \fBzero_terminate\fP modifier is provided. It causes the length to
|
||||||
|
be passed as PCRE2_ZERO_TERMINATED. (When matching via the POSIX interface,
|
||||||
|
this modifier has no effect, as there is no facility for passing a length.)
|
||||||
|
.P
|
||||||
|
When testing \fBpcre2_substitute\fP, this modifier also has the effect of
|
||||||
|
passing the replacement string as zero-terminated.
|
||||||
|
.
|
||||||
|
.
|
||||||
.SH "THE ALTERNATIVE MATCHING FUNCTION"
|
.SH "THE ALTERNATIVE MATCHING FUNCTION"
|
||||||
.rs
|
.rs
|
||||||
.sp
|
.sp
|
||||||
|
@ -1192,6 +1200,6 @@ Cambridge CB2 3QH, England.
|
||||||
.rs
|
.rs
|
||||||
.sp
|
.sp
|
||||||
.nf
|
.nf
|
||||||
Last updated: 02 November 2014
|
Last updated: 09 November 2014
|
||||||
Copyright (c) 1997-2014 University of Cambridge.
|
Copyright (c) 1997-2014 University of Cambridge.
|
||||||
.fi
|
.fi
|
||||||
|
|
|
@ -206,24 +206,25 @@ context functions. */
|
||||||
#define PCRE2_ERROR_BADMODE (-32)
|
#define PCRE2_ERROR_BADMODE (-32)
|
||||||
#define PCRE2_ERROR_BADOFFSET (-33)
|
#define PCRE2_ERROR_BADOFFSET (-33)
|
||||||
#define PCRE2_ERROR_BADOPTION (-34)
|
#define PCRE2_ERROR_BADOPTION (-34)
|
||||||
#define PCRE2_ERROR_BADUTFOFFSET (-35)
|
#define PCRE2_ERROR_BADREPLACEMENT (-35)
|
||||||
#define PCRE2_ERROR_CALLOUT (-36) /* Never used by PCRE2 itself */
|
#define PCRE2_ERROR_BADUTFOFFSET (-36)
|
||||||
#define PCRE2_ERROR_DFA_BADRESTART (-37)
|
#define PCRE2_ERROR_CALLOUT (-37) /* Never used by PCRE2 itself */
|
||||||
#define PCRE2_ERROR_DFA_RECURSE (-38)
|
#define PCRE2_ERROR_DFA_BADRESTART (-38)
|
||||||
#define PCRE2_ERROR_DFA_UCOND (-39)
|
#define PCRE2_ERROR_DFA_RECURSE (-39)
|
||||||
#define PCRE2_ERROR_DFA_UITEM (-40)
|
#define PCRE2_ERROR_DFA_UCOND (-40)
|
||||||
#define PCRE2_ERROR_DFA_WSSIZE (-41)
|
#define PCRE2_ERROR_DFA_UITEM (-41)
|
||||||
#define PCRE2_ERROR_INTERNAL (-42)
|
#define PCRE2_ERROR_DFA_WSSIZE (-42)
|
||||||
#define PCRE2_ERROR_JIT_BADOPTION (-43)
|
#define PCRE2_ERROR_INTERNAL (-43)
|
||||||
#define PCRE2_ERROR_JIT_STACKLIMIT (-44)
|
#define PCRE2_ERROR_JIT_BADOPTION (-44)
|
||||||
#define PCRE2_ERROR_MATCHLIMIT (-45)
|
#define PCRE2_ERROR_JIT_STACKLIMIT (-45)
|
||||||
#define PCRE2_ERROR_NOMEMORY (-46)
|
#define PCRE2_ERROR_MATCHLIMIT (-46)
|
||||||
#define PCRE2_ERROR_NOSUBSTRING (-47)
|
#define PCRE2_ERROR_NOMEMORY (-47)
|
||||||
#define PCRE2_ERROR_NOUNIQUESUBSTRING (-48)
|
#define PCRE2_ERROR_NOSUBSTRING (-48)
|
||||||
#define PCRE2_ERROR_NULL (-49)
|
#define PCRE2_ERROR_NOUNIQUESUBSTRING (-49)
|
||||||
#define PCRE2_ERROR_RECURSELOOP (-50)
|
#define PCRE2_ERROR_NULL (-50)
|
||||||
#define PCRE2_ERROR_RECURSIONLIMIT (-51)
|
#define PCRE2_ERROR_RECURSELOOP (-51)
|
||||||
#define PCRE2_ERROR_UNSET (-52)
|
#define PCRE2_ERROR_RECURSIONLIMIT (-52)
|
||||||
|
#define PCRE2_ERROR_UNSET (-53)
|
||||||
|
|
||||||
/* Request types for pcre2_pattern_info() */
|
/* Request types for pcre2_pattern_info() */
|
||||||
|
|
||||||
|
|
|
@ -206,24 +206,25 @@ static const char match_error_texts[] =
|
||||||
"bad offset value\0"
|
"bad offset value\0"
|
||||||
"bad option value\0"
|
"bad option value\0"
|
||||||
/* 35 */
|
/* 35 */
|
||||||
|
"invalid replacement string\0"
|
||||||
"bad offset into UTF string\0"
|
"bad offset into UTF string\0"
|
||||||
"callout error code\0" /* Never returned by PCRE2 itself */
|
"callout error code\0" /* Never returned by PCRE2 itself */
|
||||||
"invalid data in workspace for DFA restart\0"
|
"invalid data in workspace for DFA restart\0"
|
||||||
"too much recursion for DFA matching\0"
|
"too much recursion for DFA matching\0"
|
||||||
"backreference condition or recursion test not supported for DFA matching\0"
|
|
||||||
/* 40 */
|
/* 40 */
|
||||||
|
"backreference condition or recursion test not supported for DFA matching\0"
|
||||||
"item unsupported for DFA matching\0"
|
"item unsupported for DFA matching\0"
|
||||||
"workspace size exceeded in DFA matching\0"
|
"workspace size exceeded in DFA matching\0"
|
||||||
"internal error - pattern overwritten?\0"
|
"internal error - pattern overwritten?\0"
|
||||||
"bad JIT option\0"
|
"bad JIT option\0"
|
||||||
"JIT stack limit reached\0"
|
|
||||||
/* 45 */
|
/* 45 */
|
||||||
|
"JIT stack limit reached\0"
|
||||||
"match limit exceeded\0"
|
"match limit exceeded\0"
|
||||||
"no more memory\0"
|
"no more memory\0"
|
||||||
"unknown or unset substring\0"
|
"unknown or unset substring\0"
|
||||||
"non-unique substring name\0"
|
"non-unique substring name\0"
|
||||||
"NULL argument passed\0"
|
|
||||||
/* 50 */
|
/* 50 */
|
||||||
|
"NULL argument passed\0"
|
||||||
"nested recursion at the same subject position\0"
|
"nested recursion at the same subject position\0"
|
||||||
"recursion limit exceeded\0"
|
"recursion limit exceeded\0"
|
||||||
"requested value is not set\0"
|
"requested value is not set\0"
|
||||||
|
|
|
@ -51,7 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
/* This function applies a compiled re to a subject string and creates a new
|
/* This function applies a compiled re to a subject string and creates a new
|
||||||
string with substitutione. The first 7 arguments are the same as for
|
string with substitutions. The first 7 arguments are the same as for
|
||||||
pcre2_match(). Either string length may be PCRE2_ZERO_TERMINATED.
|
pcre2_match(). Either string length may be PCRE2_ZERO_TERMINATED.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
@ -69,6 +69,7 @@ Arguments:
|
||||||
|
|
||||||
Returns: > 0 number of substitutions made
|
Returns: > 0 number of substitutions made
|
||||||
< 0 an error code, including PCRE2_ERROR_NOMATCH if no match
|
< 0 an error code, including PCRE2_ERROR_NOMATCH if no match
|
||||||
|
PCRE2_ERROR_BADREPLACEMENT means invalid use of $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
|
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
|
||||||
|
@ -86,6 +87,11 @@ BOOL global = FALSE;
|
||||||
PCRE2_SIZE buff_offset, lengthleft, endlength;
|
PCRE2_SIZE buff_offset, lengthleft, endlength;
|
||||||
PCRE2_SIZE *ovector;
|
PCRE2_SIZE *ovector;
|
||||||
|
|
||||||
|
/* Partial matching is not valid. */
|
||||||
|
|
||||||
|
if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0)
|
||||||
|
return PCRE2_ERROR_BADOPTION;
|
||||||
|
|
||||||
/* If no match data block is provided, create one. */
|
/* If no match data block is provided, create one. */
|
||||||
|
|
||||||
if (match_data == NULL)
|
if (match_data == NULL)
|
||||||
|
@ -130,10 +136,15 @@ do
|
||||||
rc = pcre2_match(code, subject, length, start_offset, options|goptions,
|
rc = pcre2_match(code, subject, length, start_offset, options|goptions,
|
||||||
match_data, mcontext);
|
match_data, mcontext);
|
||||||
|
|
||||||
|
/* Any error other than no match returns the error code. No match when not
|
||||||
|
doing the special after-empty-match global rematch, or when at the end of the
|
||||||
|
subject, breaks the global loop. Otherwise, advance the starting point and
|
||||||
|
try again. */
|
||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
{
|
{
|
||||||
if (goptions == 0 || rc != PCRE2_ERROR_NOMATCH || start_offset >= length)
|
if (rc != PCRE2_ERROR_NOMATCH) goto EXIT;
|
||||||
break;
|
if (goptions == 0 || start_offset >= length) break;
|
||||||
start_offset++;
|
start_offset++;
|
||||||
if ((code->overall_options & PCRE2_UTF) != 0)
|
if ((code->overall_options & PCRE2_UTF) != 0)
|
||||||
{
|
{
|
||||||
|
@ -150,6 +161,8 @@ do
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle a successful match. */
|
||||||
|
|
||||||
subs++;
|
subs++;
|
||||||
if (rc == 0) rc = ovector_count;
|
if (rc == 0) rc = ovector_count;
|
||||||
endlength = ovector[0] - start_offset;
|
endlength = ovector[0] - start_offset;
|
||||||
|
@ -161,29 +174,34 @@ do
|
||||||
|
|
||||||
for (i = 0; i < rlength; i++)
|
for (i = 0; i < rlength; i++)
|
||||||
{
|
{
|
||||||
if (replacement[i] == CHAR_DOLLAR_SIGN && i != rlength - 1)
|
if (replacement[i] == CHAR_DOLLAR_SIGN)
|
||||||
{
|
{
|
||||||
int group = -1;
|
int group, n;
|
||||||
int n = 0;
|
BOOL inparens;
|
||||||
BOOL inparens = FALSE;
|
|
||||||
PCRE2_SIZE j = i + 1;
|
|
||||||
PCRE2_SIZE sublength;
|
PCRE2_SIZE sublength;
|
||||||
PCRE2_UCHAR next = replacement[j];
|
PCRE2_UCHAR next;
|
||||||
PCRE2_UCHAR name[33];
|
PCRE2_UCHAR name[33];
|
||||||
|
|
||||||
|
if (++i == rlength) goto BAD;
|
||||||
|
if ((next = replacement[i]) == CHAR_DOLLAR_SIGN) goto LITERAL;
|
||||||
|
|
||||||
|
group = -1;
|
||||||
|
n = 0;
|
||||||
|
inparens = FALSE;
|
||||||
|
|
||||||
if (next == CHAR_LEFT_CURLY_BRACKET)
|
if (next == CHAR_LEFT_CURLY_BRACKET)
|
||||||
{
|
{
|
||||||
if (j == rlength - 1) goto LITERAL;
|
if (++i == rlength) goto BAD;
|
||||||
|
next = replacement[i];
|
||||||
inparens = TRUE;
|
inparens = TRUE;
|
||||||
next = replacement[++j];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next >= CHAR_0 && next <= CHAR_9)
|
if (next >= CHAR_0 && next <= CHAR_9)
|
||||||
{
|
{
|
||||||
group = next - CHAR_0;
|
group = next - CHAR_0;
|
||||||
while (j < rlength - 1)
|
while (i < rlength - 1)
|
||||||
{
|
{
|
||||||
next = replacement[++j];
|
next = replacement[++i];
|
||||||
if (next < CHAR_0 || next > CHAR_9) break;
|
if (next < CHAR_0 || next > CHAR_9) break;
|
||||||
group = group * 10 + next - CHAR_0;
|
group = group * 10 + next - CHAR_0;
|
||||||
}
|
}
|
||||||
|
@ -194,23 +212,23 @@ do
|
||||||
while (MAX_255(next) && (ctypes[next] & ctype_word) != 0)
|
while (MAX_255(next) && (ctypes[next] & ctype_word) != 0)
|
||||||
{
|
{
|
||||||
name[n++] = next;
|
name[n++] = next;
|
||||||
if (n > 32) goto LITERAL;
|
if (n > 32) goto BAD;
|
||||||
if (j == rlength - 1) break;
|
if (i == rlength) break;
|
||||||
next = replacement[++j];
|
next = replacement[++i];
|
||||||
}
|
}
|
||||||
|
if (n == 0) goto BAD;
|
||||||
name[n] = 0;
|
name[n] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inparens)
|
if (inparens)
|
||||||
{
|
{
|
||||||
if (j == rlength || next != CHAR_RIGHT_CURLY_BRACKET) goto LITERAL;
|
if (i == rlength || next != CHAR_RIGHT_CURLY_BRACKET) goto BAD;
|
||||||
}
|
}
|
||||||
else j--; /* Last code unit of name/number */
|
else i--; /* Last code unit of name/number */
|
||||||
|
|
||||||
/* Have found a syntactically correct group number or name. */
|
/* Have found a syntactically correct group number or name. */
|
||||||
|
|
||||||
i = j; /* Where to continue from */
|
sublength = lengthleft;
|
||||||
|
|
||||||
if (group < 0)
|
if (group < 0)
|
||||||
rc = pcre2_substring_copy_byname(match_data, name,
|
rc = pcre2_substring_copy_byname(match_data, name,
|
||||||
buffer + buff_offset, &sublength);
|
buffer + buff_offset, &sublength);
|
||||||
|
@ -242,20 +260,16 @@ do
|
||||||
PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART;
|
PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART;
|
||||||
} while (global); /* Repeat "do" loop */
|
} while (global); /* Repeat "do" loop */
|
||||||
|
|
||||||
/* No match is a "normal" end; copy the rest of the subject and return the
|
/* Copy the rest of the subject and return the number of substitutions. */
|
||||||
number of substitutions. */
|
|
||||||
|
|
||||||
if (rc == PCRE2_ERROR_NOMATCH)
|
rc = subs;
|
||||||
{
|
endlength = length - start_offset;
|
||||||
rc = subs;
|
if (endlength + 1 > lengthleft) goto NOROOM;
|
||||||
endlength = length - start_offset;
|
memcpy(buffer + buff_offset, subject + start_offset,
|
||||||
if (endlength + 1 >= lengthleft) goto NOROOM;
|
endlength*(PCRE2_CODE_UNIT_WIDTH/8));
|
||||||
memcpy(buffer + buff_offset, subject + start_offset,
|
buff_offset += endlength;
|
||||||
endlength*(PCRE2_CODE_UNIT_WIDTH/8));
|
buffer[buff_offset] = 0;
|
||||||
buff_offset += endlength;
|
*blength = buff_offset;
|
||||||
buffer[buff_offset] = 0;
|
|
||||||
*blength = buff_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXIT:
|
EXIT:
|
||||||
if (match_data_created) pcre2_match_data_free(match_data);
|
if (match_data_created) pcre2_match_data_free(match_data);
|
||||||
|
@ -264,6 +278,10 @@ return rc;
|
||||||
NOROOM:
|
NOROOM:
|
||||||
rc = PCRE2_ERROR_NOMEMORY;
|
rc = PCRE2_ERROR_NOMEMORY;
|
||||||
goto EXIT;
|
goto EXIT;
|
||||||
|
|
||||||
|
BAD:
|
||||||
|
rc = PCRE2_ERROR_BADREPLACEMENT;
|
||||||
|
goto EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of pcre2_substitute.c */
|
/* End of pcre2_substitute.c */
|
||||||
|
|
231
src/pcre2test.c
231
src/pcre2test.c
|
@ -165,6 +165,7 @@ void vms_setsymbol( char *, char *, int );
|
||||||
#define DEFAULT_OVECCOUNT 15 /* Default ovector count */
|
#define DEFAULT_OVECCOUNT 15 /* Default ovector count */
|
||||||
#define JUNK_OFFSET 0xdeadbeef /* For initializing ovector */
|
#define JUNK_OFFSET 0xdeadbeef /* For initializing ovector */
|
||||||
#define LOOPREPEAT 500000 /* Default loop count for timing */
|
#define LOOPREPEAT 500000 /* Default loop count for timing */
|
||||||
|
#define REPLACE_BUFFSIZE 400 /* For replacement strings */
|
||||||
#define VERSION_SIZE 64 /* Size of buffer for the version strings */
|
#define VERSION_SIZE 64 /* Size of buffer for the version strings */
|
||||||
|
|
||||||
/* Execution modes */
|
/* Execution modes */
|
||||||
|
@ -345,9 +346,9 @@ either on a pattern or a data line, so they must all be distinct. */
|
||||||
#define CTL_JITVERIFY 0x00010000u
|
#define CTL_JITVERIFY 0x00010000u
|
||||||
#define CTL_MARK 0x00020000u
|
#define CTL_MARK 0x00020000u
|
||||||
#define CTL_MEMORY 0x00040000u
|
#define CTL_MEMORY 0x00040000u
|
||||||
#define CTL_PATLEN 0x00080000u
|
#define CTL_POSIX 0x00080000u
|
||||||
#define CTL_POSIX 0x00100000u
|
#define CTL_STARTCHAR 0x00100000u
|
||||||
#define CTL_STARTCHAR 0x00200000u
|
#define CTL_ZERO_TERMINATE 0x00200000u
|
||||||
|
|
||||||
#define CTL_BSR_SET 0x80000000u /* This is informational */
|
#define CTL_BSR_SET 0x80000000u /* This is informational */
|
||||||
#define CTL_NL_SET 0x40000000u /* This is informational */
|
#define CTL_NL_SET 0x40000000u /* This is informational */
|
||||||
|
@ -376,6 +377,7 @@ typedef struct patctl { /* Structure for pattern modifiers. */
|
||||||
uint32_t stackguard_test;
|
uint32_t stackguard_test;
|
||||||
uint32_t tables_id;
|
uint32_t tables_id;
|
||||||
uint8_t locale[32];
|
uint8_t locale[32];
|
||||||
|
uint8_t replacement[REPLACE_BUFFSIZE];
|
||||||
} patctl;
|
} patctl;
|
||||||
|
|
||||||
#define MAXCPYGET 10
|
#define MAXCPYGET 10
|
||||||
|
@ -485,13 +487,14 @@ static modstruct modlist[] = {
|
||||||
{ "posix", MOD_PAT, MOD_CTL, CTL_POSIX, PO(control) },
|
{ "posix", MOD_PAT, MOD_CTL, CTL_POSIX, PO(control) },
|
||||||
{ "ps", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_SOFT, DO(options) },
|
{ "ps", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_SOFT, DO(options) },
|
||||||
{ "recursion_limit", MOD_CTM, MOD_INT, 0, MO(recursion_limit) },
|
{ "recursion_limit", MOD_CTM, MOD_INT, 0, MO(recursion_limit) },
|
||||||
|
{ "replace", MOD_PAT, MOD_STR, 0, PO(replacement) },
|
||||||
{ "stackguard", MOD_PAT, MOD_INT, 0, PO(stackguard_test) },
|
{ "stackguard", MOD_PAT, MOD_INT, 0, PO(stackguard_test) },
|
||||||
{ "startchar", MOD_PND, MOD_CTL, CTL_STARTCHAR, PO(control) },
|
{ "startchar", MOD_PND, MOD_CTL, CTL_STARTCHAR, PO(control) },
|
||||||
{ "tables", MOD_PAT, MOD_INT, 0, PO(tables_id) },
|
{ "tables", MOD_PAT, MOD_INT, 0, PO(tables_id) },
|
||||||
{ "ucp", MOD_PATP, MOD_OPT, PCRE2_UCP, PO(options) },
|
{ "ucp", MOD_PATP, MOD_OPT, PCRE2_UCP, PO(options) },
|
||||||
{ "ungreedy", MOD_PAT, MOD_OPT, PCRE2_UNGREEDY, PO(options) },
|
{ "ungreedy", MOD_PAT, MOD_OPT, PCRE2_UNGREEDY, PO(options) },
|
||||||
{ "use_length", MOD_PAT, MOD_CTL, CTL_PATLEN, PO(control) },
|
{ "utf", MOD_PATP, MOD_OPT, PCRE2_UTF, PO(options) },
|
||||||
{ "utf", MOD_PATP, MOD_OPT, PCRE2_UTF, PO(options) }
|
{ "zero_terminate", MOD_DAT, MOD_CTL, CTL_ZERO_TERMINATE, DO(control) }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MODLISTCOUNT sizeof(modlist)/sizeof(modstruct)
|
#define MODLISTCOUNT sizeof(modlist)/sizeof(modstruct)
|
||||||
|
@ -945,6 +948,17 @@ are supported. */
|
||||||
else \
|
else \
|
||||||
pcre2_set_recursion_limit_32(G(a,32),b)
|
pcre2_set_recursion_limit_32(G(a,32),b)
|
||||||
|
|
||||||
|
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
|
||||||
|
if (test_mode == PCRE8_MODE) \
|
||||||
|
a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \
|
||||||
|
(PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l); \
|
||||||
|
else if (test_mode == PCRE16_MODE) \
|
||||||
|
a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16), \
|
||||||
|
(PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l); \
|
||||||
|
else \
|
||||||
|
a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32), \
|
||||||
|
(PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)
|
||||||
|
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
||||||
if (test_mode == PCRE8_MODE) \
|
if (test_mode == PCRE8_MODE) \
|
||||||
a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e); \
|
a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e); \
|
||||||
|
@ -1298,6 +1312,16 @@ the three different cases. */
|
||||||
else \
|
else \
|
||||||
G(pcre2_set_recursion_limit_,BITTWO)(G(a,BITTWO),b)
|
G(pcre2_set_recursion_limit_,BITTWO)(G(a,BITTWO),b)
|
||||||
|
|
||||||
|
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
|
||||||
|
if (test_mode == G(G(PCRE,BITONE),_MODE)) \
|
||||||
|
a = G(pcre2_substitute_,BITONE)(G(b,BITONE),(G(PCRE2_SPTR,BITONE))c,d,e,f, \
|
||||||
|
G(g,BITONE),G(h,BITONE),(G(PCRE2_SPTR,BITONE))i,j, \
|
||||||
|
(G(PCRE2_UCHAR,BITONE) *)k,l); \
|
||||||
|
else \
|
||||||
|
a = G(pcre2_substitute_,BITTWO)(G(b,BITTWO),(G(PCRE2_SPTR,BITTWO))c,d,e,f, \
|
||||||
|
G(g,BITTWO),G(h,BITTWO),(G(PCRE2_SPTR,BITTWO))i,j, \
|
||||||
|
(G(PCRE2_UCHAR,BITTWO) *)k,l)
|
||||||
|
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
||||||
if (test_mode == G(G(PCRE,BITONE),_MODE)) \
|
if (test_mode == G(G(PCRE,BITONE),_MODE)) \
|
||||||
a = G(pcre2_substring_copy_byname_,BITONE)(G(b,BITONE),G(c,BITONE),\
|
a = G(pcre2_substring_copy_byname_,BITONE)(G(b,BITONE),G(c,BITONE),\
|
||||||
|
@ -1466,6 +1490,9 @@ the three different cases. */
|
||||||
#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_8(G(a,8),b)
|
#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_8(G(a,8),b)
|
||||||
#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_8(G(a,8),b)
|
#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_8(G(a,8),b)
|
||||||
#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_8(G(a,8),b)
|
#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_8(G(a,8),b)
|
||||||
|
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
|
||||||
|
a = pcre2_substitute_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8), \
|
||||||
|
(PCRE2_SPTR8)i,j,(PCRE2_UCHAR8 *)k,l)
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
||||||
a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e)
|
a = pcre2_substring_copy_byname_8(G(b,8),G(c,8),(PCRE2_UCHAR8 *)d,e)
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \
|
#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \
|
||||||
|
@ -1544,6 +1571,9 @@ the three different cases. */
|
||||||
#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_16(G(a,16),b)
|
#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_16(G(a,16),b)
|
||||||
#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_16(G(a,16),b)
|
#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_16(G(a,16),b)
|
||||||
#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_16(G(a,16),b)
|
#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_16(G(a,16),b)
|
||||||
|
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
|
||||||
|
a = pcre2_substitute_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16), \
|
||||||
|
(PCRE2_SPTR16)i,j,(PCRE2_UCHAR16 *)k,l)
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
||||||
a = pcre2_substring_copy_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 *)d,e)
|
a = pcre2_substring_copy_byname_16(G(b,16),G(c,16),(PCRE2_UCHAR16 *)d,e)
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \
|
#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \
|
||||||
|
@ -1622,6 +1652,9 @@ the three different cases. */
|
||||||
#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_32(G(a,32),b)
|
#define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_32(G(a,32),b)
|
||||||
#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_32(G(a,32),b)
|
#define PCRE2_SET_PARENS_NEST_LIMIT(a,b) pcre2_set_parens_nest_limit_32(G(a,32),b)
|
||||||
#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_32(G(a,32),b)
|
#define PCRE2_SET_RECURSION_LIMIT(a,b) pcre2_set_recursion_limit_32(G(a,32),b)
|
||||||
|
#define PCRE2_SUBSTITUTE(a,b,c,d,e,f,g,h,i,j,k,l) \
|
||||||
|
a = pcre2_substitute_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32), \
|
||||||
|
(PCRE2_SPTR32)i,j,(PCRE2_UCHAR32 *)k,l)
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
#define PCRE2_SUBSTRING_COPY_BYNAME(a,b,c,d,e) \
|
||||||
a = pcre2_substring_copy_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 *)d,e)
|
a = pcre2_substring_copy_byname_32(G(b,32),G(c,32),(PCRE2_UCHAR32 *)d,e)
|
||||||
#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \
|
#define PCRE2_SUBSTRING_COPY_BYNUMBER(a,b,c,d,e) \
|
||||||
|
@ -3199,9 +3232,9 @@ fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||||
((controls & CTL_JITVERIFY) != 0)? " jitverify" : "",
|
((controls & CTL_JITVERIFY) != 0)? " jitverify" : "",
|
||||||
((controls & CTL_MARK) != 0)? " mark" : "",
|
((controls & CTL_MARK) != 0)? " mark" : "",
|
||||||
((controls & CTL_MEMORY) != 0)? " memory" : "",
|
((controls & CTL_MEMORY) != 0)? " memory" : "",
|
||||||
((controls & CTL_PATLEN) != 0)? " use_length" : "",
|
|
||||||
((controls & CTL_POSIX) != 0)? " posix" : "",
|
((controls & CTL_POSIX) != 0)? " posix" : "",
|
||||||
((controls & CTL_STARTCHAR) != 0)? " startchar" : "");
|
((controls & CTL_STARTCHAR) != 0)? " startchar" : "",
|
||||||
|
((controls & CTL_ZERO_TERMINATE) != 0)? " zero_terminate" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3672,6 +3705,7 @@ 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;
|
||||||
|
utf = (pat_patctl.options & PCRE2_UTF) != 0;
|
||||||
|
|
||||||
/* Assume full JIT compile for jitverify and/or jitfast if nothing else was
|
/* Assume full JIT compile for jitverify and/or jitfast if nothing else was
|
||||||
specified. */
|
specified. */
|
||||||
|
@ -3679,7 +3713,6 @@ specified. */
|
||||||
if (pat_patctl.jit == 0 &&
|
if (pat_patctl.jit == 0 &&
|
||||||
(pat_patctl.control & (CTL_JITVERIFY|CTL_JITFAST)) != 0)
|
(pat_patctl.control & (CTL_JITVERIFY|CTL_JITFAST)) != 0)
|
||||||
pat_patctl.jit = 7;
|
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
|
/* Now copy the pattern to pbuffer8 for use in 8-bit testing and for reflecting
|
||||||
in callouts. Convert to binary if required. */
|
in callouts. Convert to binary if required. */
|
||||||
|
@ -3786,6 +3819,7 @@ if ((pat_patctl.control & CTL_POSIX) != 0)
|
||||||
/* Check for features that the POSIX interface does not support. */
|
/* Check for features that the POSIX interface does not support. */
|
||||||
|
|
||||||
if (pat_patctl.locale[0] != 0) prmsg(&msg, "locale");
|
if (pat_patctl.locale[0] != 0) prmsg(&msg, "locale");
|
||||||
|
if (pat_patctl.replacement[0] != 0) prmsg(&msg, "replace");
|
||||||
if (pat_patctl.tables_id != 0) prmsg(&msg, "tables");
|
if (pat_patctl.tables_id != 0) prmsg(&msg, "tables");
|
||||||
if (pat_patctl.stackguard_test != 0) prmsg(&msg, "stackguard");
|
if (pat_patctl.stackguard_test != 0) prmsg(&msg, "stackguard");
|
||||||
if (timeit > 0) prmsg(&msg, "timing");
|
if (timeit > 0) prmsg(&msg, "timing");
|
||||||
|
@ -3863,11 +3897,11 @@ switch(errorcode)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The pattern in now in pbuffer[8|16|32], with the length in patlen. By
|
/* The pattern is now in pbuffer[8|16|32], with the length in patlen. By
|
||||||
default, however, we pass a zero-terminated pattern. The length is passed only
|
default, however, we pass a zero-terminated pattern. The length is passed only
|
||||||
if we had a hex pattern or if use_length was set. */
|
if we had a hex pattern. */
|
||||||
|
|
||||||
if ((pat_patctl.control & (CTL_PATLEN|CTL_HEXPAT)) == 0) patlen = -1;
|
if ((pat_patctl.control & CTL_HEXPAT) == 0) patlen = PCRE2_ZERO_TERMINATED;
|
||||||
|
|
||||||
/* Compile many times when timing. */
|
/* Compile many times when timing. */
|
||||||
|
|
||||||
|
@ -4491,22 +4525,6 @@ SET(*q, 0);
|
||||||
len = CASTVAR(uint8_t *, q) - dbuffer; /* Length in bytes */
|
len = CASTVAR(uint8_t *, q) - dbuffer; /* Length in bytes */
|
||||||
ulen = len/code_unit_size; /* Length in code units */
|
ulen = len/code_unit_size; /* Length in code units */
|
||||||
|
|
||||||
/* If we have explicit valgrind support, mark the data from after its end to
|
|
||||||
the end of the buffer as unaddressable, so that a read over the end of the
|
|
||||||
buffer will be seen by valgrind, even if it doesn't cause a crash. If we're not
|
|
||||||
building with valgrind support, at least move the data to the end of the buffer
|
|
||||||
so that it might at least cause a crash. If we are using the POSIX interface,
|
|
||||||
we must include the terminating zero. */
|
|
||||||
|
|
||||||
pp = dbuffer;
|
|
||||||
c = code_unit_size * ((pat_patctl.control & CTL_POSIX) != 0)? 1:0;
|
|
||||||
|
|
||||||
#ifdef SUPPORT_VALGRIND
|
|
||||||
VALGRIND_MAKE_MEM_NOACCESS(dbuffer + len + c, dbuffer_size - (len + c));
|
|
||||||
#else
|
|
||||||
pp = memmove(pp + dbuffer_size - len - c, pp, len + c);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If the string was terminated by \= we must now interpret modifiers. */
|
/* If the string was terminated by \= we must now interpret modifiers. */
|
||||||
|
|
||||||
if (p[-1] != 0 && !decode_modifiers(p, CTX_DAT, NULL, &dat_datctl))
|
if (p[-1] != 0 && !decode_modifiers(p, CTX_DAT, NULL, &dat_datctl))
|
||||||
|
@ -4522,10 +4540,27 @@ if (c - (c & -c) != 0)
|
||||||
return PR_OK;
|
return PR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now run the pattern match: len contains the byte length, ulen contains the
|
/* If we have explicit valgrind support, mark the data from after its end to
|
||||||
code unit length, and pp points to the subject string. POSIX matching is only
|
the end of the buffer as unaddressable, so that a read over the end of the
|
||||||
possible in 8-bit mode, and it does not support timing or other fancy features.
|
buffer will be seen by valgrind, even if it doesn't cause a crash. If we're not
|
||||||
Some were checked at compile time, but we need to check the match-time settings
|
building with valgrind support, at least move the data to the end of the buffer
|
||||||
|
so that it might at least cause a crash. If we are using the POSIX interface,
|
||||||
|
or testing zero-termination, we must include the terminating zero. */
|
||||||
|
|
||||||
|
pp = dbuffer;
|
||||||
|
c = code_unit_size * (((pat_patctl.control & CTL_POSIX) +
|
||||||
|
(dat_datctl.control & CTL_ZERO_TERMINATE) != 0)? 1:0);
|
||||||
|
|
||||||
|
#ifdef SUPPORT_VALGRIND
|
||||||
|
VALGRIND_MAKE_MEM_NOACCESS(dbuffer + len + c, dbuffer_size - (len + c));
|
||||||
|
#else
|
||||||
|
pp = memmove(pp + dbuffer_size - len - c, pp, len + c);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We now have len containing the byte length, ulen containing the code unit
|
||||||
|
length, and pp pointing to the subject string. POSIX matching is only possible
|
||||||
|
in 8-bit mode, and it does not support timing or other fancy features. Some
|
||||||
|
were checked at compile time, but we need to check the match-time settings
|
||||||
here. */
|
here. */
|
||||||
|
|
||||||
#ifdef SUPPORT_PCRE2_8
|
#ifdef SUPPORT_PCRE2_8
|
||||||
|
@ -4621,6 +4656,11 @@ if ((dat_datctl.control & (CTL_ALLUSEDTEXT|CTL_DFA)) == CTL_ALLUSEDTEXT &&
|
||||||
dat_datctl.control &= ~CTL_ALLUSEDTEXT;
|
dat_datctl.control &= ~CTL_ALLUSEDTEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle passing the subject as zero-terminated. */
|
||||||
|
|
||||||
|
if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)
|
||||||
|
ulen = PCRE2_ZERO_TERMINATED;
|
||||||
|
|
||||||
/* Enable display of malloc/free if wanted. */
|
/* Enable display of malloc/free if wanted. */
|
||||||
|
|
||||||
show_memory = (dat_datctl.control & CTL_MEMORY) != 0;
|
show_memory = (dat_datctl.control & CTL_MEMORY) != 0;
|
||||||
|
@ -4676,9 +4716,134 @@ else
|
||||||
PCRE2_MATCH_DATA_CREATE(match_data, max_oveccount, NULL);
|
PCRE2_MATCH_DATA_CREATE(match_data, max_oveccount, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop for global matching */
|
/* If a replacement string is provided, call pcre2_substitute() instead of one
|
||||||
|
of the matching functions. First we have to convert the replacement string to
|
||||||
|
the appropriate width. */
|
||||||
|
|
||||||
for (gmatched = 0;; gmatched++)
|
if (pat_patctl.replacement[0] != 0)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
uint8_t *pr;
|
||||||
|
uint8_t rbuffer[REPLACE_BUFFSIZE];
|
||||||
|
uint8_t nbuffer[REPLACE_BUFFSIZE];
|
||||||
|
uint32_t goption;
|
||||||
|
PCRE2_SIZE rlen;
|
||||||
|
PCRE2_SIZE nsize;
|
||||||
|
|
||||||
|
#ifdef SUPPORT_PCRE2_8
|
||||||
|
uint8_t *r8 = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef SUPPORT_PCRE2_16
|
||||||
|
uint16_t *r16 = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef SUPPORT_PCRE2_32
|
||||||
|
uint32_t *r32 = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
goption = ((pat_patctl.control & CTL_GLOBAL) == 0)? 0 :
|
||||||
|
PCRE2_SUBSTITUTE_GLOBAL;
|
||||||
|
SETCASTPTR(r, rbuffer); /* Sets r8, r16, or r32, as appropriate. */
|
||||||
|
pr = pat_patctl.replacement;
|
||||||
|
|
||||||
|
/* If the replacement starts with '[<number>]' we interpret that as length
|
||||||
|
value for the replacement buffer. */
|
||||||
|
|
||||||
|
nsize = REPLACE_BUFFSIZE/code_unit_size;
|
||||||
|
if (*pr == '[')
|
||||||
|
{
|
||||||
|
PCRE2_SIZE n = 0;
|
||||||
|
while ((c = *(++pr)) >= CHAR_0 && c <= CHAR_9) n = n * 10 + c - CHAR_0;
|
||||||
|
if (*pr++ != ']')
|
||||||
|
{
|
||||||
|
fprintf(outfile, "Bad buffer size in replacement string\n");
|
||||||
|
return PR_OK;
|
||||||
|
}
|
||||||
|
if (n > nsize)
|
||||||
|
{
|
||||||
|
fprintf(outfile, "Replacement buffer setting (%ld) is too large "
|
||||||
|
"(max %ld)\n", n, nsize);
|
||||||
|
return PR_OK;
|
||||||
|
}
|
||||||
|
nsize = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now copy the replacement string to a buffer of the appropriate width. */
|
||||||
|
|
||||||
|
while ((c = *pr++) != 0)
|
||||||
|
{
|
||||||
|
if (utf && HASUTF8EXTRALEN(c)) { GETUTF8INC(c, pr); }
|
||||||
|
|
||||||
|
/* At present no escape processing is provided for replacements. */
|
||||||
|
|
||||||
|
#ifdef SUPPORT_PCRE2_8
|
||||||
|
if (test_mode == PCRE8_MODE)
|
||||||
|
{
|
||||||
|
if (utf)
|
||||||
|
{
|
||||||
|
r8 += ord2utf8(c, r8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*r8++ = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef SUPPORT_PCRE2_16
|
||||||
|
if (test_mode == PCRE16_MODE)
|
||||||
|
{
|
||||||
|
if (utf)
|
||||||
|
{
|
||||||
|
if (c >= 0x10000u)
|
||||||
|
{
|
||||||
|
c-= 0x10000u;
|
||||||
|
*r16++ = 0xD800 | (c >> 10);
|
||||||
|
*r16++ = 0xDC00 | (c & 0x3ff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*r16++ = c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*r16++ = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef SUPPORT_PCRE2_32
|
||||||
|
if (test_mode == PCRE32_MODE)
|
||||||
|
{
|
||||||
|
*r32++ = c;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SET(*r, 0);
|
||||||
|
if ((dat_datctl.control & CTL_ZERO_TERMINATE) != 0)
|
||||||
|
rlen = PCRE2_ZERO_TERMINATED;
|
||||||
|
else
|
||||||
|
rlen = (CASTVAR(uint8_t *, r) - rbuffer)/code_unit_size;
|
||||||
|
PCRE2_SUBSTITUTE(rc, compiled_code, pp, ulen, dat_datctl.offset,
|
||||||
|
dat_datctl.options|goption, match_data, dat_context,
|
||||||
|
rbuffer, rlen, nbuffer, &nsize);
|
||||||
|
|
||||||
|
if (rc < 0)
|
||||||
|
{
|
||||||
|
fprintf(outfile, "Failed: error %d: ", rc);
|
||||||
|
PCRE2_GET_ERROR_MESSAGE(nsize, rc, pbuffer);
|
||||||
|
PCHARSV(CASTVAR(void *, pbuffer), 0, nsize, FALSE, outfile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(outfile, "%2d: ", rc);
|
||||||
|
PCHARSV(nbuffer, 0, nsize, utf, outfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(outfile, "\n");
|
||||||
|
} /* End of substitution handling */
|
||||||
|
|
||||||
|
/* When a replacement string is not provided, run a loop for global matching
|
||||||
|
with one of the basic matching functions. */
|
||||||
|
|
||||||
|
else for (gmatched = 0;; gmatched++)
|
||||||
{
|
{
|
||||||
PCRE2_SIZE j;
|
PCRE2_SIZE j;
|
||||||
int capcount;
|
int capcount;
|
||||||
|
|
|
@ -384,15 +384,15 @@ aaaaa2
|
||||||
010203040506
|
010203040506
|
||||||
RC=0
|
RC=0
|
||||||
======== STDERR ========
|
======== STDERR ========
|
||||||
pcre2grep: pcre2_match() gave error -45 while matching this text:
|
pcre2grep: pcre2_match() gave error -46 while matching this text:
|
||||||
|
|
||||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
|
||||||
pcre2grep: pcre2_match() gave error -45 while matching this text:
|
pcre2grep: pcre2_match() gave error -46 while matching this text:
|
||||||
|
|
||||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
|
||||||
pcre2grep: Error -44, -45 or -51 means that a resource limit was exceeded.
|
pcre2grep: Error -45, -46 or -52 means that a resource limit was exceeded.
|
||||||
pcre2grep: Check your regex for nested unlimited loops.
|
pcre2grep: Check your regex for nested unlimited loops.
|
||||||
---------------------------- Test 38 ------------------------------
|
---------------------------- Test 38 ------------------------------
|
||||||
This line contains a binary zero here > |