Implemented pcre2_code_copy().
This commit is contained in:
parent
6a3b36fa15
commit
96926349bc
|
@ -69,6 +69,9 @@ identification.
|
|||
a report of compiler warnings from Visual Studio 2013 and a few tests with
|
||||
gcc's -Wconversion (which still throws up a lot).
|
||||
|
||||
15. Implemented pcre2_code_copy(), and added pushcopy and #popcopy to pcre2test
|
||||
for testing it.
|
||||
|
||||
|
||||
Version 10.21 12-January-2016
|
||||
-----------------------------
|
||||
|
|
|
@ -25,6 +25,7 @@ dist_html_DATA = \
|
|||
doc/html/pcre2-config.html \
|
||||
doc/html/pcre2.html \
|
||||
doc/html/pcre2_callout_enumerate.html \
|
||||
doc/html/pcre2_code_copy.html \
|
||||
doc/html/pcre2_code_free.html \
|
||||
doc/html/pcre2_compile.html \
|
||||
doc/html/pcre2_compile_context_copy.html \
|
||||
|
@ -105,6 +106,7 @@ dist_man_MANS = \
|
|||
doc/pcre2-config.1 \
|
||||
doc/pcre2.3 \
|
||||
doc/pcre2_callout_enumerate.3 \
|
||||
doc/pcre2_code_copy.3 \
|
||||
doc/pcre2_code_free.3 \
|
||||
doc/pcre2_compile.3 \
|
||||
doc/pcre2_compile_context_copy.3 \
|
||||
|
|
2
RunTest
2
RunTest
|
@ -74,7 +74,7 @@ title16="Test 16: JIT-specific features when JIT is not available"
|
|||
title17="Test 17: JIT-specific features when JIT is available"
|
||||
title18="Test 18: Tests of the POSIX interface, excluding UTF/UCP"
|
||||
title19="Test 19: Tests of the POSIX interface with UTF/UCP"
|
||||
title20="Test 20: Serialization tests"
|
||||
title20="Test 20: Serialization and code copy tests"
|
||||
title21="Test 21: \C tests without UTF (supported for DFA matching)"
|
||||
title22="Test 22: \C tests with UTF (not supported for DFA matching)"
|
||||
title23="Test 23: \C disabled test"
|
||||
|
|
|
@ -91,6 +91,9 @@ in the library.
|
|||
<tr><td><a href="pcre2_callout_enumerate.html">pcre2_callout_enumerate</a></td>
|
||||
<td> Enumerate callouts in a compiled pattern</td></tr>
|
||||
|
||||
<tr><td><a href="pcre2_code_copy.html">pcre2_code_copy</a></td>
|
||||
<td> Copy a compiled pattern</td></tr>
|
||||
|
||||
<tr><td><a href="pcre2_code_free.html">pcre2_code_free</a></td>
|
||||
<td> Free a compiled pattern</td></tr>
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
.TH PCRE2_CODE_COPY 3 "26 February 2016" "PCRE2 10.22"
|
||||
.SH NAME
|
||||
PCRE2 - Perl-compatible regular expressions (revised API)
|
||||
.SH SYNOPSIS
|
||||
.rs
|
||||
.sp
|
||||
.B #include <pcre2.h>
|
||||
.PP
|
||||
.nf
|
||||
.B pcre2_code *pcre2_code_copy(const pcre2_code *\fIcode\fP);
|
||||
.fi
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
.rs
|
||||
.sp
|
||||
This function makes a copy of the memory used for a compiled pattern, excluding
|
||||
any memory used by the JIT compiler. Without a subsequent call to
|
||||
\fBpcre2_jit_compile()\fP, the copy can be used only for non-JIT matching. The
|
||||
yield of the function is NULL if \fIcode\fP is NULL or if sufficient memory
|
||||
cannot be obtained.
|
||||
.P
|
||||
There is a complete description of the PCRE2 native API in the
|
||||
.\" HREF
|
||||
\fBpcre2api\fP
|
||||
.\"
|
||||
page and a description of the POSIX API in the
|
||||
.\" HREF
|
||||
\fBpcre2posix\fP
|
||||
.\"
|
||||
page.
|
|
@ -1,4 +1,4 @@
|
|||
.TH PCRE2API 3 "25 February 2016" "PCRE2 10.22"
|
||||
.TH PCRE2API 3 "26 February 2016" "PCRE2 10.22"
|
||||
.SH NAME
|
||||
PCRE2 - Perl-compatible regular expressions (revised API)
|
||||
.sp
|
||||
|
@ -233,6 +233,8 @@ document for an overview of all the PCRE2 documentation.
|
|||
.rs
|
||||
.sp
|
||||
.nf
|
||||
.B pcre2_code *pcre2_code_copy(const pcre2_code *\fIcode\fP);
|
||||
.sp
|
||||
.B int pcre2_get_error_message(int \fIerrorcode\fP, PCRE2_UCHAR *\fIbuffer\fP,
|
||||
.B " PCRE2_SIZE \fIbufflen\fP);"
|
||||
.sp
|
||||
|
@ -506,7 +508,8 @@ If JIT is being used, but the JIT compilation is not being done immediately,
|
|||
(perhaps waiting to see if the pattern is used often enough) similar logic is
|
||||
required. JIT compilation updates a pointer within the compiled code block, so
|
||||
a thread must gain unique write access to the pointer before calling
|
||||
\fBpcre2_jit_compile()\fP.
|
||||
\fBpcre2_jit_compile()\fP. Alternatively, \fBpcre2_code_copy()\fP can be used
|
||||
to obtain a private copy of the compiled code.
|
||||
.
|
||||
.
|
||||
.SS "Context blocks"
|
||||
|
@ -1020,14 +1023,33 @@ zero.
|
|||
.B " pcre2_compile_context *\fIccontext\fP);"
|
||||
.sp
|
||||
.B void pcre2_code_free(pcre2_code *\fIcode\fP);
|
||||
.sp
|
||||
.B pcre2_code *pcre2_code_copy(const pcre2_code *\fIcode\fP);
|
||||
.fi
|
||||
.P
|
||||
The \fBpcre2_compile()\fP function compiles a pattern into an internal form.
|
||||
The pattern is defined by a pointer to a string of code units and a length, If
|
||||
The pattern is defined by a pointer to a string of code units and a length. If
|
||||
the pattern is zero-terminated, the length can be specified as
|
||||
PCRE2_ZERO_TERMINATED. The function returns a pointer to a block of memory that
|
||||
contains the compiled pattern and related data. The caller must free the memory
|
||||
by calling \fBpcre2_code_free()\fP when it is no longer needed.
|
||||
contains the compiled pattern and related data.
|
||||
.P
|
||||
If the compile context argument \fIccontext\fP is NULL, memory for the compiled
|
||||
pattern is obtained by calling \fBmalloc()\fP. Otherwise, it is obtained from
|
||||
the same memory function that was used for the compile context. The caller must
|
||||
free the memory by calling \fBpcre2_code_free()\fP when it is no longer needed.
|
||||
.P
|
||||
The function \fBpcre2_code_copy()\fP makes a copy of the compiled code in new
|
||||
memory, using the same memory allocator as was used for the original. However,
|
||||
if the code has been processed by the JIT compiler (see
|
||||
.\" HTML <a href="#jitcompiling">
|
||||
.\" </a>
|
||||
below),
|
||||
.\"
|
||||
the JIT information cannot be copied (because it is position-dependent).
|
||||
The new copy can initially be used only for non-JIT matching, though it can be
|
||||
passed to \fBpcre2_jit_compile()\fP if required. The \fBpcre2_code_copy()\fP
|
||||
function provides a way for individual threads in a multithreaded application
|
||||
to acquire a private copy of shared compiled code.
|
||||
.P
|
||||
NOTE: When one of the matching functions is called, pointers to the compiled
|
||||
pattern and the subject string are set in the match data block so that they can
|
||||
|
@ -1039,15 +1061,12 @@ match data block
|
|||
.\"
|
||||
have taken place.
|
||||
.P
|
||||
If the compile context argument \fIccontext\fP is NULL, memory for the compiled
|
||||
pattern is obtained by calling \fBmalloc()\fP. Otherwise, it is obtained from
|
||||
the same memory function that was used for the compile context.
|
||||
.P
|
||||
The \fIoptions\fP argument contains various bit settings that affect the
|
||||
compilation. It should be zero if no options are required. The available
|
||||
options are described below. Some of them (in particular, those that are
|
||||
compatible with Perl, but some others as well) can also be set and unset from
|
||||
within the pattern (see the detailed description in the
|
||||
The \fIoptions\fP argument for \fBpcre2_compile()\fP contains various bit
|
||||
settings that affect the compilation. It should be zero if no options are
|
||||
required. The available options are described below. Some of them (in
|
||||
particular, those that are compatible with Perl, but some others as well) can
|
||||
also be set and unset from within the pattern (see the detailed description in
|
||||
the
|
||||
.\" HREF
|
||||
\fBpcre2pattern\fP
|
||||
.\"
|
||||
|
@ -1470,6 +1489,7 @@ page. The \fBpcre2_get_error_message()\fP function can be called to obtain a
|
|||
textual error message from any error code.
|
||||
.
|
||||
.
|
||||
.\" HTML <a name="jitcompiling"></a>
|
||||
.SH "JUST-IN-TIME (JIT) COMPILATION"
|
||||
.rs
|
||||
.sp
|
||||
|
@ -3209,6 +3229,6 @@ Cambridge, England.
|
|||
.rs
|
||||
.sp
|
||||
.nf
|
||||
Last updated: 25 February 2016
|
||||
Last updated: 26 February 2016
|
||||
Copyright (c) 1997-2016 University of Cambridge.
|
||||
.fi
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH PCRE2TEST 1 "06 February 2016" "PCRE 10.22"
|
||||
.TH PCRE2TEST 1 "26 February 2016" "PCRE 10.22"
|
||||
.SH NAME
|
||||
pcre2test - a program for testing Perl-compatible regular expressions.
|
||||
.SH SYNOPSIS
|
||||
|
@ -306,9 +306,10 @@ test files that are also processed by \fBperltest.sh\fP. The \fB#perltest\fP
|
|||
command helps detect tests that are accidentally put in the wrong file.
|
||||
.sp
|
||||
#pop [<modifiers>]
|
||||
#popcopy [<modifiers>]
|
||||
.sp
|
||||
This command is used to manipulate the stack of compiled patterns, as described
|
||||
in the section entitled "Saving and restoring compiled patterns"
|
||||
These commands are used to manipulate the stack of compiled patterns, as
|
||||
described in the section entitled "Saving and restoring compiled patterns"
|
||||
.\" HTML <a href="#saverestore">
|
||||
.\" </a>
|
||||
below.
|
||||
|
@ -537,6 +538,7 @@ about the pattern:
|
|||
posix use the POSIX API
|
||||
posix_nosub use the POSIX API with REG_NOSUB
|
||||
push push compiled pattern onto the stack
|
||||
pushcopy push a copy onto the stack
|
||||
stackguard=<number> test the stackguard feature
|
||||
tables=[0|1|2] select internal tables
|
||||
.sp
|
||||
|
@ -895,13 +897,17 @@ facility is used when saving compiled patterns to a file, as described in the
|
|||
section entitled "Saving and restoring compiled patterns"
|
||||
.\" HTML <a href="#saverestore">
|
||||
.\" </a>
|
||||
below.
|
||||
below. If \fBpushcopy\fP is used instead of \fBpush\fP, a copy of the compiled
|
||||
pattern is stacked, leaving the original as current, ready to match the
|
||||
following input lines. This provides a way of testing the
|
||||
\fBpcre2_code_copy()\fP function.
|
||||
.\"
|
||||
The \fBpush\fP modifier is incompatible with compilation modifiers such as
|
||||
\fBglobal\fP that act at match time. Any that are specified are ignored, with a
|
||||
warning message, except for \fBreplace\fP, which causes an error. Note that,
|
||||
\fBjitverify\fP, which is allowed, does not carry through to any subsequent
|
||||
matching that uses this pattern.
|
||||
The \fBpush\fP and \fBpushcopy \fP modifiers are incompatible with compilation
|
||||
modifiers such as \fBglobal\fP that act at match time. Any that are specified
|
||||
are ignored (for the stacked copy), with a warning message, except for
|
||||
\fBreplace\fP, which causes an error. Note that \fBjitverify\fP, which is
|
||||
allowed, does not carry through to any subsequent matching that uses a stacked
|
||||
pattern.
|
||||
.
|
||||
.
|
||||
.\" HTML <a name="subjectmodifiers"></a>
|
||||
|
@ -1590,11 +1596,15 @@ can be used to test these functions.
|
|||
.P
|
||||
When a pattern with \fBpush\fP modifier is successfully compiled, it is pushed
|
||||
onto a stack of compiled patterns, and \fBpcre2test\fP expects the next line to
|
||||
contain a new pattern (or command) instead of a subject line. By this means, a
|
||||
number of patterns can be compiled and retained. The \fBpush\fP modifier is
|
||||
incompatible with \fBposix\fP, and control modifiers that act at match time are
|
||||
ignored (with a message). The \fBjitverify\fP modifier applies only at compile
|
||||
time. The command
|
||||
contain a new pattern (or command) instead of a subject line. By contrast,
|
||||
the \fBpushcopy\fP modifier causes a copy of the compiled pattern to be
|
||||
stacked, leaving the original available for immediate matching. By using
|
||||
\fBpush\fP and/or \fBpushcopy\fP, a number of patterns can be compiled and
|
||||
retained. These modifiers are incompatible with \fBposix\fP, and control
|
||||
modifiers that act at match time are ignored (with a message) for the stacked
|
||||
patterns. The \fBjitverify\fP modifier applies only at compile time.
|
||||
.P
|
||||
The command
|
||||
.sp
|
||||
#save <filename>
|
||||
.sp
|
||||
|
@ -1614,7 +1624,8 @@ modifier list containing only
|
|||
control modifiers
|
||||
.\"
|
||||
that act after a pattern has been compiled. In particular, \fBhex\fP,
|
||||
\fBposix\fP, \fBposix_nosub\fP, and \fBpush\fP are not allowed, nor are any
|
||||
\fBposix\fP, \fBposix_nosub\fP, \fBpush\fP, and \fBpushcopy\fP are not allowed,
|
||||
nor are any
|
||||
.\" HTML <a href="#optionmodifiers">
|
||||
.\" </a>
|
||||
option-setting modifiers.
|
||||
|
@ -1634,6 +1645,10 @@ reloads two patterns.
|
|||
.sp
|
||||
If \fBjitverify\fP is used with #pop, it does not automatically imply
|
||||
\fBjit\fP, which is different behaviour from when it is used on a pattern.
|
||||
.P
|
||||
The #popcopy command is analagous to the \fBpushcopy\fP modifier in that it
|
||||
makes current a copy of the topmost stack pattern, leaving the original still
|
||||
on the stack.
|
||||
.
|
||||
.
|
||||
.
|
||||
|
|
|
@ -436,7 +436,9 @@ PCRE2_EXP_DECL int pcre2_set_recursion_memory_management( \
|
|||
PCRE2_EXP_DECL \
|
||||
pcre2_code *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, \
|
||||
int *, PCRE2_SIZE *, pcre2_compile_context *); \
|
||||
PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *);
|
||||
PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); \
|
||||
PCRE2_EXP_DECL \
|
||||
pcre2_code *pcre2_code_copy(const pcre2_code *);
|
||||
|
||||
|
||||
/* Functions that give information about a compiled pattern. */
|
||||
|
@ -585,6 +587,7 @@ pcre2_compile are called by application code. */
|
|||
/* Functions: the complete list in alphabetical order */
|
||||
|
||||
#define pcre2_callout_enumerate PCRE2_SUFFIX(pcre2_callout_enumerate_)
|
||||
#define pcre2_code_copy PCRE2_SUFFIX(pcre2_code_copy_)
|
||||
#define pcre2_code_free PCRE2_SUFFIX(pcre2_code_free_)
|
||||
#define pcre2_compile PCRE2_SUFFIX(pcre2_compile_)
|
||||
#define pcre2_compile_context_copy PCRE2_SUFFIX(pcre2_compile_context_copy_)
|
||||
|
|
|
@ -436,7 +436,9 @@ PCRE2_EXP_DECL int pcre2_set_recursion_memory_management( \
|
|||
PCRE2_EXP_DECL \
|
||||
pcre2_code *pcre2_compile(PCRE2_SPTR, PCRE2_SIZE, uint32_t, \
|
||||
int *, PCRE2_SIZE *, pcre2_compile_context *); \
|
||||
PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *);
|
||||
PCRE2_EXP_DECL void pcre2_code_free(pcre2_code *); \
|
||||
PCRE2_EXP_DECL \
|
||||
pcre2_code *pcre2_code_copy(const pcre2_code *);
|
||||
|
||||
|
||||
/* Functions that give information about a compiled pattern. */
|
||||
|
@ -585,6 +587,7 @@ pcre2_compile are called by application code. */
|
|||
/* Functions: the complete list in alphabetical order */
|
||||
|
||||
#define pcre2_callout_enumerate PCRE2_SUFFIX(pcre2_callout_enumerate_)
|
||||
#define pcre2_code_copy PCRE2_SUFFIX(pcre2_code_copy_)
|
||||
#define pcre2_code_free PCRE2_SUFFIX(pcre2_code_free_)
|
||||
#define pcre2_compile PCRE2_SUFFIX(pcre2_compile_)
|
||||
#define pcre2_compile_context_copy PCRE2_SUFFIX(pcre2_compile_context_copy_)
|
||||
|
|
|
@ -729,6 +729,39 @@ static const uint8_t opcode_possessify[] = {
|
|||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Copy compiled code *
|
||||
*************************************************/
|
||||
|
||||
/* Compiled JIT code cannot be copied, so the new compiled block has no
|
||||
associated JIT data. */
|
||||
|
||||
PCRE2_EXP_DEFN pcre2_code * PCRE2_CALL_CONVENTION
|
||||
pcre2_code_copy(const pcre2_code *code)
|
||||
{
|
||||
PCRE2_SIZE* ref_count;
|
||||
pcre2_code *newcode;
|
||||
|
||||
if (code == NULL) return NULL;
|
||||
newcode = code->memctl.malloc(code->blocksize, code->memctl.memory_data);
|
||||
if (newcode == NULL) return NULL;
|
||||
memcpy(newcode, code, code->blocksize);
|
||||
newcode->executable_jit = NULL;
|
||||
|
||||
/* If the code is one that has been deserialized, increment the reference count
|
||||
in the decoded tables. */
|
||||
|
||||
if ((code->flags & PCRE2_DEREF_TABLES) != 0)
|
||||
{
|
||||
ref_count = (PCRE2_SIZE *)(code->tables + tables_length);
|
||||
(*ref_count)++;
|
||||
}
|
||||
|
||||
return newcode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Free compiled code *
|
||||
*************************************************/
|
||||
|
|
|
@ -353,7 +353,7 @@ typedef struct cmdstruct {
|
|||
} cmdstruct;
|
||||
|
||||
enum { CMD_FORBID_UTF, CMD_LOAD, CMD_NEWLINE_DEFAULT, CMD_PATTERN,
|
||||
CMD_PERLTEST, CMD_POP, CMD_SAVE, CMD_SUBJECT, CMD_UNKNOWN };
|
||||
CMD_PERLTEST, CMD_POP, CMD_POPCOPY, CMD_SAVE, CMD_SUBJECT, CMD_UNKNOWN };
|
||||
|
||||
static cmdstruct cmdlist[] = {
|
||||
{ "forbid_utf", CMD_FORBID_UTF },
|
||||
|
@ -362,6 +362,7 @@ static cmdstruct cmdlist[] = {
|
|||
{ "pattern", CMD_PATTERN },
|
||||
{ "perltest", CMD_PERLTEST },
|
||||
{ "pop", CMD_POP },
|
||||
{ "popcopy", CMD_POPCOPY },
|
||||
{ "save", CMD_SAVE },
|
||||
{ "subject", CMD_SUBJECT }};
|
||||
|
||||
|
@ -427,9 +428,9 @@ so many of them that they are split into two fields. */
|
|||
#define CTL_POSIX 0x00400000u
|
||||
#define CTL_POSIX_NOSUB 0x00800000u
|
||||
#define CTL_PUSH 0x01000000u
|
||||
#define CTL_STARTCHAR 0x02000000u
|
||||
#define CTL_ZERO_TERMINATE 0x04000000u
|
||||
/* Spare 0x08000000u */
|
||||
#define CTL_PUSHCOPY 0x02000000u
|
||||
#define CTL_STARTCHAR 0x04000000u
|
||||
#define CTL_ZERO_TERMINATE 0x08000000u
|
||||
/* Spare 0x10000000u */
|
||||
/* Spare 0x20000000u */
|
||||
#define CTL_NL_SET 0x40000000u /* Informational */
|
||||
|
@ -603,6 +604,7 @@ static modstruct modlist[] = {
|
|||
{ "posix_nosub", MOD_PAT, MOD_CTL, CTL_POSIX|CTL_POSIX_NOSUB, PO(control) },
|
||||
{ "ps", MOD_DAT, MOD_OPT, PCRE2_PARTIAL_SOFT, DO(options) },
|
||||
{ "push", MOD_PAT, MOD_CTL, CTL_PUSH, PO(control) },
|
||||
{ "pushcopy", MOD_PAT, MOD_CTL, CTL_PUSHCOPY, PO(control) },
|
||||
{ "recursion_limit", MOD_CTM, MOD_INT, 0, MO(recursion_limit) },
|
||||
{ "regerror_buffsize", MOD_PAT, MOD_INT, 0, PO(regerror_buffsize) },
|
||||
{ "replace", MOD_PND, MOD_STR, REPLACE_MODSIZE, PO(replacement) },
|
||||
|
@ -644,7 +646,7 @@ static modstruct modlist[] = {
|
|||
|
||||
#define PUSH_SUPPORTED_COMPILE_CONTROLS ( \
|
||||
CTL_BINCODE|CTL_CALLOUT_INFO|CTL_FULLBINCODE|CTL_HEXPAT|CTL_INFO| \
|
||||
CTL_JITVERIFY|CTL_MEMORY|CTL_PUSH|CTL_BSR_SET|CTL_NL_SET)
|
||||
CTL_JITVERIFY|CTL_MEMORY|CTL_PUSH|CTL_PUSHCOPY|CTL_BSR_SET|CTL_NL_SET)
|
||||
|
||||
#define PUSH_SUPPORTED_COMPILE_CONTROLS2 (0)
|
||||
|
||||
|
@ -653,9 +655,10 @@ static modstruct modlist[] = {
|
|||
#define PUSH_COMPILE_ONLY_CONTROLS CTL_JITVERIFY
|
||||
#define PUSH_COMPILE_ONLY_CONTROLS2 (0)
|
||||
|
||||
/* Controls that are forbidden with #pop. */
|
||||
/* Controls that are forbidden with #pop or #popcopy. */
|
||||
|
||||
#define NOTPOP_CONTROLS (CTL_HEXPAT|CTL_POSIX|CTL_POSIX_NOSUB|CTL_PUSH)
|
||||
#define NOTPOP_CONTROLS (CTL_HEXPAT|CTL_POSIX|CTL_POSIX_NOSUB|CTL_PUSH| \
|
||||
CTL_PUSHCOPY)
|
||||
|
||||
/* Pattern controls that are mutually exclusive. At present these are all in
|
||||
the first control word. Note that CTL_POSIX_NOSUB is always accompanied by
|
||||
|
@ -664,6 +667,7 @@ CTL_POSIX, so it doesn't need its own entries. */
|
|||
static uint32_t exclusive_pat_controls[] = {
|
||||
CTL_POSIX | CTL_HEXPAT,
|
||||
CTL_POSIX | CTL_PUSH,
|
||||
CTL_POSIX | CTL_PUSHCOPY,
|
||||
CTL_EXPAND | CTL_HEXPAT };
|
||||
|
||||
/* Data controls that are mutually exclusive. At present these are all in the
|
||||
|
@ -945,6 +949,22 @@ are supported. */
|
|||
a = pcre2_callout_enumerate_32(compiled_code32, \
|
||||
(int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c)
|
||||
|
||||
#define PCRE2_CODE_COPY_FROM_VOID(a,b) \
|
||||
if (test_mode == PCRE8_MODE) \
|
||||
G(a,8) = pcre2_code_copy_8(b); \
|
||||
else if (test_mode == PCRE16_MODE) \
|
||||
G(a,16) = pcre2_code_copy_16(b); \
|
||||
else \
|
||||
G(a,32) = pcre2_code_copy_32(b)
|
||||
|
||||
#define PCRE2_CODE_COPY_TO_VOID(a,b) \
|
||||
if (test_mode == PCRE8_MODE) \
|
||||
a = (void *)pcre2_code_copy_8(G(b,8)); \
|
||||
else if (test_mode == PCRE16_MODE) \
|
||||
a = (void *)pcre2_code_copy_16(G(b,16)); \
|
||||
else \
|
||||
a = (void *)pcre2_code_copy_32(G(b,32))
|
||||
|
||||
#define PCRE2_COMPILE(a,b,c,d,e,f,g) \
|
||||
if (test_mode == PCRE8_MODE) \
|
||||
G(a,8) = pcre2_compile_8(G(b,8),c,d,e,f,g); \
|
||||
|
@ -1396,6 +1416,18 @@ the three different cases. */
|
|||
a = G(pcre2_callout_enumerate,BITTWO)(G(compiled_code,BITTWO), \
|
||||
(int (*)(struct G(pcre2_callout_enumerate_block_,BITTWO) *, void *))b,c)
|
||||
|
||||
#define PCRE2_CODE_COPY_FROM_VOID(a,b) \
|
||||
if (test_mode == G(G(PCRE,BITONE),_MODE)) \
|
||||
G(a,BITONE) = G(pcre2_code_copy_,BITONE)(b); \
|
||||
else \
|
||||
G(a,BITTWO) = G(pcre2_code_copy_,BITTWO)(b)
|
||||
|
||||
#define PCRE2_CODE_COPY_TO_VOID(a,b) \
|
||||
if (test_mode == G(G(PCRE,BITONE),_MODE)) \
|
||||
a = (void *)G(pcre2_code_copy_,BITONE)(G(b,BITONE)); \
|
||||
else \
|
||||
a = (void *)G(pcre2_code_copy_,BITTWO)(G(b,BITTWO))
|
||||
|
||||
#define PCRE2_COMPILE(a,b,c,d,e,f,g) \
|
||||
if (test_mode == G(G(PCRE,BITONE),_MODE)) \
|
||||
G(a,BITONE) = G(pcre2_compile_,BITONE)(G(b,BITONE),c,d,e,f,g); \
|
||||
|
@ -1731,6 +1763,8 @@ the three different cases. */
|
|||
#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \
|
||||
a = pcre2_callout_enumerate_8(compiled_code8, \
|
||||
(int (*)(struct pcre2_callout_enumerate_block_8 *, void *))b,c)
|
||||
#define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,8) = pcre2_code_copy_8(b)
|
||||
#define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_8(G(b,8))
|
||||
#define PCRE2_COMPILE(a,b,c,d,e,f,g) \
|
||||
G(a,8) = pcre2_compile_8(G(b,8),c,d,e,f,g)
|
||||
#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
|
||||
|
@ -1824,6 +1858,8 @@ the three different cases. */
|
|||
#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \
|
||||
a = pcre2_callout_enumerate_16(compiled_code16, \
|
||||
(int (*)(struct pcre2_callout_enumerate_block_16 *, void *))b,c)
|
||||
#define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,16) = pcre2_code_copy_16(b)
|
||||
#define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_16(G(b,16))
|
||||
#define PCRE2_COMPILE(a,b,c,d,e,f,g) \
|
||||
G(a,16) = pcre2_compile_16(G(b,16),c,d,e,f,g)
|
||||
#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
|
||||
|
@ -1917,6 +1953,8 @@ the three different cases. */
|
|||
#define PCRE2_CALLOUT_ENUMERATE(a,b,c) \
|
||||
a = pcre2_callout_enumerate_32(compiled_code32, \
|
||||
(int (*)(struct pcre2_callout_enumerate_block_32 *, void *))b,c)
|
||||
#define PCRE2_CODE_COPY_FROM_VOID(a,b) G(a,32) = pcre2_code_copy_32(b)
|
||||
#define PCRE2_CODE_COPY_TO_VOID(a,b) a = (void *)pcre2_code_copy_32(G(b,32))
|
||||
#define PCRE2_COMPILE(a,b,c,d,e,f,g) \
|
||||
G(a,32) = pcre2_compile_32(G(b,32),c,d,e,f,g)
|
||||
#define PCRE2_DFA_MATCH(a,b,c,d,e,f,g,h,i,j) \
|
||||
|
@ -3584,7 +3622,7 @@ Returns: nothing
|
|||
static void
|
||||
show_controls(uint32_t controls, uint32_t controls2, const char *before)
|
||||
{
|
||||
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%s%s%s%s%s%s%s%s%s%s%s",
|
||||
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%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
before,
|
||||
((controls & CTL_AFTERTEXT) != 0)? " aftertext" : "",
|
||||
((controls & CTL_ALLAFTERTEXT) != 0)? " allaftertext" : "",
|
||||
|
@ -3613,6 +3651,7 @@ 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%s%s%s%s%s%s%s%s
|
|||
((controls & CTL_POSIX) != 0)? " posix" : "",
|
||||
((controls & CTL_POSIX_NOSUB) != 0)? " posix_nosub" : "",
|
||||
((controls & CTL_PUSH) != 0)? " push" : "",
|
||||
((controls & CTL_PUSHCOPY) != 0)? " pushcopy" : "",
|
||||
((controls & CTL_STARTCHAR) != 0)? " startchar" : "",
|
||||
((controls2 & CTL2_SUBSTITUTE_EXTENDED) != 0)? " substitute_extended" : "",
|
||||
((controls2 & CTL2_SUBSTITUTE_OVERFLOW_LENGTH) != 0)? " substitute_overflow_length" : "",
|
||||
|
@ -4260,11 +4299,12 @@ switch(cmd)
|
|||
local_newline_default = first_listed_newline;
|
||||
break;
|
||||
|
||||
/* Pop a compiled pattern off the stack. Modifiers that do not affect the
|
||||
compiled pattern (e.g. to give information) are permitted. The default
|
||||
/* Pop or copy a compiled pattern off the stack. Modifiers that do not affect
|
||||
the compiled pattern (e.g. to give information) are permitted. The default
|
||||
pattern modifiers are ignored. */
|
||||
|
||||
case CMD_POP:
|
||||
case CMD_POPCOPY:
|
||||
if (patstacknext <= 0)
|
||||
{
|
||||
fprintf(outfile, "** Can't pop off an empty stack\n");
|
||||
|
@ -4273,7 +4313,16 @@ switch(cmd)
|
|||
memset(&pat_patctl, 0, sizeof(patctl)); /* Completely unset */
|
||||
if (!decode_modifiers(argptr, CTX_POPPAT, &pat_patctl, NULL))
|
||||
return PR_SKIP;
|
||||
SET(compiled_code, patstack[--patstacknext]);
|
||||
|
||||
if (cmd == CMD_POP)
|
||||
{
|
||||
SET(compiled_code, patstack[--patstacknext]);
|
||||
}
|
||||
else
|
||||
{
|
||||
PCRE2_CODE_COPY_FROM_VOID(compiled_code, patstack[patstacknext - 1]);
|
||||
}
|
||||
|
||||
if (pat_patctl.jit != 0)
|
||||
{
|
||||
PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
|
||||
|
@ -4769,7 +4818,7 @@ if ((pat_patctl.control & CTL_POSIX) != 0)
|
|||
/* Handle compiling via the native interface. Controls that act later are
|
||||
ignored with "push". Replacements are locked out. */
|
||||
|
||||
if ((pat_patctl.control & CTL_PUSH) != 0)
|
||||
if ((pat_patctl.control & (CTL_PUSH|CTL_PUSHCOPY)) != 0)
|
||||
{
|
||||
if (pat_patctl.replacement[0] != 0)
|
||||
{
|
||||
|
@ -4972,6 +5021,19 @@ if ((pat_patctl.control & CTL_PUSH) != 0)
|
|||
SET(compiled_code, NULL);
|
||||
}
|
||||
|
||||
/* The "pushcopy" control is similar, but pushes a copy of the pattern. This
|
||||
tests the pcre2_code_copy() function. */
|
||||
|
||||
if ((pat_patctl.control & CTL_PUSHCOPY) != 0)
|
||||
{
|
||||
if (patstacknext >= PATSTACKSIZE)
|
||||
{
|
||||
fprintf(outfile, "** Too many pushed patterns (max %d)\n", PATSTACKSIZE);
|
||||
return PR_ABEND;
|
||||
}
|
||||
PCRE2_CODE_COPY_TO_VOID(patstack[patstacknext++], compiled_code);
|
||||
}
|
||||
|
||||
return PR_OK;
|
||||
}
|
||||
|
||||
|
@ -5116,10 +5178,10 @@ if (f != NULL) fprintf(f, "--->");
|
|||
|
||||
PCHARS(pre_start, cb->subject, 0, cb->start_match, utf, f);
|
||||
|
||||
/* If a lookbehind is involved, the current position may be earlier than the
|
||||
/* If a lookbehind is involved, the current position may be earlier than the
|
||||
match start. If so, use the match start instead. */
|
||||
|
||||
current_position = (cb->current_position >= cb->start_match)?
|
||||
current_position = (cb->current_position >= cb->start_match)?
|
||||
cb->current_position : cb->start_match;
|
||||
|
||||
/* The subject between the match start and the current position. */
|
||||
|
@ -5129,7 +5191,7 @@ PCHARS(post_start, cb->subject, cb->start_match,
|
|||
|
||||
/* Print from the current position to the end. */
|
||||
|
||||
PCHARSV(cb->subject, current_position, cb->subject_length - current_position,
|
||||
PCHARSV(cb->subject, current_position, cb->subject_length - current_position,
|
||||
utf, f);
|
||||
|
||||
/* Calculate the total subject printed length (no print). */
|
||||
|
|
|
@ -213,6 +213,12 @@
|
|||
#pop jit,jitverify
|
||||
abcdef
|
||||
|
||||
/abcd/pushcopy,jitverify
|
||||
abcd
|
||||
|
||||
#pop jitverify
|
||||
abcd
|
||||
|
||||
# Test pattern compilation
|
||||
|
||||
/(?:a|b|c|d|e)(?R)/jit=1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# This set of tests exercises the serialization/deserialization functions in
|
||||
# the library. It does not use UTF or JIT.
|
||||
# This set of tests exercises the serialization/deserialization and code copy
|
||||
# functions in the library. It does not use UTF or JIT.
|
||||
|
||||
#forbid_utf
|
||||
|
||||
|
@ -59,5 +59,33 @@
|
|||
|
||||
#pop should give an error
|
||||
pqr
|
||||
|
||||
/abcd/pushcopy
|
||||
abcd
|
||||
|
||||
#pop
|
||||
abcd
|
||||
|
||||
#pop should give an error
|
||||
|
||||
/abcd/push
|
||||
#popcopy
|
||||
abcd
|
||||
|
||||
#pop
|
||||
abcd
|
||||
|
||||
/abcd/push
|
||||
#save testsaved1
|
||||
#pop should give an error
|
||||
|
||||
#load testsaved1
|
||||
#popcopy
|
||||
abcd
|
||||
|
||||
#pop
|
||||
abcd
|
||||
|
||||
#pop should give an error
|
||||
|
||||
# End of testinput20
|
||||
|
|
|
@ -392,6 +392,15 @@ JIT compilation was successful
|
|||
abcdef
|
||||
0: def (JIT)
|
||||
|
||||
/abcd/pushcopy,jitverify
|
||||
** Applies only to compile when pattern is stacked with 'push': jitverify
|
||||
abcd
|
||||
0: abcd (JIT)
|
||||
|
||||
#pop jitverify
|
||||
abcd
|
||||
0: abcd
|
||||
|
||||
# Test pattern compilation
|
||||
|
||||
/(?:a|b|c|d|e)(?R)/jit=1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# This set of tests exercises the serialization/deserialization functions in
|
||||
# the library. It does not use UTF or JIT.
|
||||
# This set of tests exercises the serialization/deserialization and code copy
|
||||
# functions in the library. It does not use UTF or JIT.
|
||||
|
||||
#forbid_utf
|
||||
|
||||
|
@ -97,5 +97,42 @@ Serialization failed: error -30: patterns do not all use the same character tabl
|
|||
#pop should give an error
|
||||
** Can't pop off an empty stack
|
||||
pqr
|
||||
|
||||
/abcd/pushcopy
|
||||
abcd
|
||||
0: abcd
|
||||
|
||||
#pop
|
||||
abcd
|
||||
0: abcd
|
||||
|
||||
#pop should give an error
|
||||
** Can't pop off an empty stack
|
||||
|
||||
/abcd/push
|
||||
#popcopy
|
||||
abcd
|
||||
0: abcd
|
||||
|
||||
#pop
|
||||
abcd
|
||||
0: abcd
|
||||
|
||||
/abcd/push
|
||||
#save testsaved1
|
||||
#pop should give an error
|
||||
** Can't pop off an empty stack
|
||||
|
||||
#load testsaved1
|
||||
#popcopy
|
||||
abcd
|
||||
0: abcd
|
||||
|
||||
#pop
|
||||
abcd
|
||||
0: abcd
|
||||
|
||||
#pop should give an error
|
||||
** Can't pop off an empty stack
|
||||
|
||||
# End of testinput20
|
||||
|
|
Loading…
Reference in New Issue