There are also individual pages that summarize the interface for each function
-in the library:
+in the library. There is a single page for each pair of 8-bit/16-bit functions.
pcre-config returns the configuration of the installed PCRE
-libraries and the options required to compile a program to use them.
+libraries and the options required to compile a program to use them. Some of
+the options apply only to the 8-bit or 16-bit libraries, respectively, and are
+not available if only one of those libraries has been built. If an unavailable
+option is encountered, the "usage" information is output.
--libs
Writes to the standard output the command line options required to link
-with PCRE (-lpcre on many systems).
+with the 8-bit PCRE library (-lpcre on many systems).
+
+
+--libs16
+Writes to the standard output the command line options required to link
+with the 16-bit PCRE library (-lpcre16 on many systems).
+
+
+--libs-cpp
+Writes to the standard output the command line options required to link with
+PCRE's C++ wrapper library (-lpcrecpp-lpcre on many
+systems).
--libs-posix
Writes to the standard output the command line options required to link with
-the PCRE posix emulation library (-lpcreposix-lpcre on many
+PCRE's POSIX API wrapper library (-lpcreposix-lpcre on many
systems).
@@ -67,7 +82,7 @@
--cflags-posix
Writes to the standard output the command line options required to compile
-files that use the PCRE posix emulation library (this may include some -I
+files that use PCRE's POSIX API wrapper library (this may include some -I
options, but is blank on many systems).
This manual page was originally written by Mark Baker for the Debian GNU/Linux
-system. It has been slightly revised as a generic PCRE man page.
+system. It has been subsequently revised as a generic PCRE man page.
@@ -30,10 +28,29 @@
for requesting some minor changes that give better JavaScript compatibility.
+Starting with release 8.30, it is possible to compile two separate PCRE
+libraries: the original, which supports 8-bit character strings (including
+UTF-8 strings), and a second library that supports 16-bit character strings
+(including UTF-16 strings). The build process allows either one or both to be
+built. The majority of the work to make this possible was done by Zoltan
+Herczeg.
+
+
+The two libraries contain identical sets of functions, except that the names in
+the 16-bit library start with pcre16_ instead of pcre_. To avoid
+over-complication and reduce the documentation maintenance load, most of the
+documentation describes the 8-bit library, with the differences for the 16-bit
+library described separately in the
+pcre16
+page. References to functions or structures of the form pcre[16]_xxx
+should be read as meaning "pcre_xxx when using the 8-bit library and
+pcre16_xxx when using the 16-bit library".
+
+
The current implementation of PCRE corresponds approximately with Perl 5.12,
-including support for UTF-8 encoded strings and Unicode general category
-properties. However, UTF-8 and Unicode support has to be explicitly enabled; it
-is not the default. The Unicode tables correspond to Unicode release 5.2.0.
+including support for UTF-8/16 encoded strings and Unicode general category
+properties. However, UTF-8/16 and Unicode support has to be explicitly enabled;
+it is not the default. The Unicode tables correspond to Unicode release 6.0.0.
In addition to the Perl-compatible matching function, PCRE contains an
@@ -46,8 +63,8 @@
PCRE is written in C and released as a C library. A number of people have
written wrappers and interfaces of various kinds. In particular, Google Inc.
-have provided a comprehensive C++ wrapper. This is now included as part of the
-PCRE distribution. The
+have provided a comprehensive C++ wrapper for the 8-bit library. This is now
+included as part of the PCRE distribution. The
pcrecpp
page has details of this interface. Other people's contributions can be found
in the Contrib directory at the primary FTP site, which is:
@@ -75,13 +92,13 @@
distribution.
-The library contains a number of undocumented internal functions and data
+The libraries contains a number of undocumented internal functions and data
tables that are used by more than one of the exported external functions, but
which are not intended for use by external callers. Their names all begin with
-"_pcre_", which hopefully will not provoke any name clashes. In some
-environments, it is possible to control which external symbols are exported
-when a shared library is built, and in these cases the undocumented symbols are
-not exported.
+"_pcre_" or "_pcre16_", which hopefully will not provoke any name clashes. In
+some environments, it is possible to control which external symbols are
+exported when a shared library is built, and in these cases the undocumented
+symbols are not exported.
@@ -92,204 +109,33 @@
of searching. The sections are as follows:
pcre this document
+ pcre16 details of the 16-bit library
pcre-config show PCRE installation configuration information
pcreapi details of PCRE's native C API
pcrebuild options for building PCRE
pcrecallout details of the callout feature
pcrecompat discussion of Perl compatibility
- pcrecpp details of the C++ wrapper
+ pcrecpp details of the C++ wrapper for the 8-bit library
pcredemo a demonstration C program that uses PCRE
- pcregrep description of the pcregrep command
+ pcregrep description of the pcregrep command (8-bit only)
+ pcrejit discussion of the just-in-time optimization support
+ pcrelimits details of size and other limits
pcrematching discussion of the two matching algorithms
pcrepartial details of the partial matching facility
pcrepattern syntax and semantics of supported regular expressions
pcreperform discussion of performance issues
- pcreposix the POSIX-compatible C API
+ pcreposix the POSIX-compatible C API for the 8-bit library
pcreprecompile details of saving and re-using precompiled patterns
pcresample discussion of the pcredemo program
pcrestack discussion of stack usage
pcresyntax quick syntax reference
pcretest description of the pcretest testing command
+ pcreunicode discussion of Unicode and UTF-8/16 support
In addition, in the "man" and HTML formats, there is a short page for each
-C library function, listing its arguments and results.
-
-There are some size limitations in PCRE but it is hoped that they will never in
-practice be relevant.
-
-
-The maximum length of a compiled pattern is 65539 (sic) bytes if PCRE is
-compiled with the default internal linkage size of 2. If you want to process
-regular expressions that are truly enormous, you can compile PCRE with an
-internal linkage size of 3 or 4 (see the README file in the source
-distribution and the
-pcrebuild
-documentation for details). In these cases the limit is substantially larger.
-However, the speed of execution is slower.
-
-
-All values in repeating quantifiers must be less than 65536.
-
-
-There is no limit to the number of parenthesized subpatterns, but there can be
-no more than 65535 capturing subpatterns.
-
-
-The maximum length of name for a named subpattern is 32 characters, and the
-maximum number of named subpatterns is 10000.
-
-
-The maximum length of a subject string is the largest positive number that an
-integer variable can hold. However, when using the traditional matching
-function, PCRE uses recursion to handle subpatterns and indefinite repetition.
-This means that the available stack space may limit the size of a subject
-string that can be processed by certain patterns. For a discussion of stack
-issues, see the
-pcrestack
-documentation.
-
-From release 3.3, PCRE has had some support for character strings encoded in
-the UTF-8 format. For release 4.0 this was greatly extended to cover most
-common requirements, and in release 5.0 additional support for Unicode general
-category properties was added.
-
-
-In order process UTF-8 strings, you must build PCRE to include UTF-8 support in
-the code, and, in addition, you must call
-pcre_compile()
-with the PCRE_UTF8 option flag, or the pattern must start with the sequence
-(*UTF8). When either of these is the case, both the pattern and any subject
-strings that are matched against it are treated as UTF-8 strings instead of
-strings of 1-byte characters.
-
-
-If you compile PCRE with UTF-8 support, but do not use it at run time, the
-library will be a bit bigger, but the additional run time overhead is limited
-to testing the PCRE_UTF8 flag occasionally, so should not be very big.
-
-
-If PCRE is built with Unicode character property support (which implies UTF-8
-support), the escape sequences \p{..}, \P{..}, and \X are supported.
-The available properties that can be tested are limited to the general
-category properties such as Lu for an upper case letter or Nd for a decimal
-number, the Unicode script names such as Arabic or Han, and the derived
-properties Any and L&. A full list is given in the
-pcrepattern
-documentation. Only the short names for properties are supported. For example,
-\p{L} matches a letter. Its Perl synonym, \p{Letter}, is not supported.
-Furthermore, in Perl, many properties may optionally be prefixed by "Is", for
-compatibility with Perl 5.6. PCRE does not support this.
-
-
-Validity of UTF-8 strings
-
-
-When you set the PCRE_UTF8 flag, the strings passed as patterns and subjects
-are (by default) checked for validity on entry to the relevant functions. From
-release 7.3 of PCRE, the check is according the rules of RFC 3629, which are
-themselves derived from the Unicode specification. Earlier releases of PCRE
-followed the rules of RFC 2279, which allows the full range of 31-bit values (0
-to 0x7FFFFFFF). The current check allows only values in the range U+0 to
-U+10FFFF, excluding U+D800 to U+DFFF.
-
-
-The excluded code points are the "Low Surrogate Area" of Unicode, of which the
-Unicode Standard says this: "The Low Surrogate Area does not contain any
-character assignments, consequently no character code charts or namelists are
-provided for this area. Surrogates are reserved for use with UTF-16 and then
-must be used in pairs." The code points that are encoded by UTF-16 pairs are
-available as independent code points in the UTF-8 encoding. (In other words,
-the whole surrogate thing is a fudge for UTF-16 which unfortunately messes up
-UTF-8.)
-
-
-If an invalid UTF-8 string is passed to PCRE, an error return
-(PCRE_ERROR_BADUTF8) is given. In some situations, you may already know that
-your strings are valid, and therefore want to skip these checks in order to
-improve performance. If you set the PCRE_NO_UTF8_CHECK flag at compile time or
-at run time, PCRE assumes that the pattern or subject it is given
-(respectively) contains only valid UTF-8 codes. In this case, it does not
-diagnose an invalid UTF-8 string.
-
-
-If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, what
-happens depends on why the string is invalid. If the string conforms to the
-"old" definition of UTF-8 (RFC 2279), it is processed as a string of characters
-in the range 0 to 0x7FFFFFFF. In other words, apart from the initial validity
-test, PCRE (when in UTF-8 mode) handles strings according to the more liberal
-rules of RFC 2279. However, if the string does not even conform to RFC 2279,
-the result is undefined. Your program may crash.
-
-
-If you want to process strings of values in the full range 0 to 0x7FFFFFFF,
-encoded in a UTF-8-like manner as per the old RFC, you can set
-PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in this
-situation, you will have to apply your own validity check.
-
-
-General comments about UTF-8 mode
-
-
-1. An unbraced hexadecimal escape sequence (such as \xb3) matches a two-byte
-UTF-8 character if the value is greater than 127.
-
-
-2. Octal numbers up to \777 are recognized, and match two-byte UTF-8
-characters for values greater than \177.
-
-
-3. Repeat quantifiers apply to complete UTF-8 characters, not to individual
-bytes, for example: \x{100}{3}.
-
-
-4. The dot metacharacter matches one UTF-8 character instead of a single byte.
-
-
-5. The escape sequence \C can be used to match a single byte in UTF-8 mode,
-but its use can lead to some strange effects. This facility is not available in
-the alternative matching function, pcre_dfa_exec().
-
-
-6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly
-test characters of any code value, but, by default, the characters that PCRE
-recognizes as digits, spaces, or word characters remain the same set as before,
-all with values less than 256. This remains true even when PCRE is built to
-include Unicode property support, because to do otherwise would slow down PCRE
-in many common cases. Note in particular that this applies to \b and \B,
-because they are defined in terms of \w and \W. If you really want to test
-for a wider sense of, say, "digit", you can use explicit Unicode property tests
-such as \p{Nd}. Alternatively, if you set the PCRE_UCP option, the way that
-the character escapes work is changed so that Unicode properties are used to
-determine which characters match. There are more details in the section on
-generic character types
-in the
-pcrepattern
-documentation.
-
-
-7. Similarly, characters that match the POSIX named character classes are all
-low-valued characters, unless the PCRE_UCP option is set.
-
-
-8. However, the horizontal and vertical whitespace matching escapes (\h, \H,
-\v, and \V) do match all the appropriate Unicode characters, whether or not
-PCRE_UCP is set.
-
-
-9. Case-insensitive matching applies only to characters whose values are less
-than 128, unless PCRE is built with Unicode property support. Even when Unicode
-property support is available, PCRE still uses its own character tables when
-checking the case of low-valued characters, so as not to degrade performance.
-The Unicode property information is used only for characters with higher
-values. Furthermore, PCRE supports case-insensitive matching only when there is
-a one-to-one mapping between a letter's cases. There are a small number of
-many-to-one mappings in Unicode; these are not supported by PCRE.
+8-bit C library function, listing its arguments and results.
Philip Hazel
@@ -303,11 +149,11 @@
taken it away. If you want to email me, use my two initials, followed by the
two digits 10, at the domain cam.ac.uk.
+This page is part of the PCRE HTML documentation. It was generated automatically
+from the original man page. If there is any nonsense in it, please consult the
+man page, in case the conversion went wrong.
+
+
+pcre16 *pcre16_compile(PCRE_SPTR16 pattern, int options,
+const char **errptr, int *erroffset,
+const unsigned char *tableptr);
+
+
+pcre16 *pcre16_compile2(PCRE_SPTR16 pattern, int options,
+int *errorcodeptr,
+const char **errptr, int *erroffset,
+const unsigned char *tableptr);
+
+
+pcre16_extra *pcre16_study(const pcre16 *code, int options,
+const char **errptr);
+
+
+void pcre16_free_study(pcre16_extra *extra);
+
+
+int pcre16_exec(const pcre16 *code, const pcre16_extra *extra,
+PCRE_SPTR16 subject, int length, int startoffset,
+int options, int *ovector, int ovecsize);
+
+
+int pcre16_dfa_exec(const pcre16 *code, const pcre16_extra *extra,
+PCRE_SPTR16 subject, int length, int startoffset,
+int options, int *ovector, int ovecsize,
+int *workspace, int wscount);
+
+Starting with release 8.30, it is possible to compile a PCRE library that
+supports 16-bit character strings, including UTF-16 strings, as well as or
+instead of the original 8-bit library. The majority of the work to make this
+possible was done by Zoltan Herczeg. The two libraries contain identical sets
+of functions, used in exactly the same way. Only the names of the functions and
+the data types of their arguments and results are different. To avoid
+over-complication and reduce the documentation maintenance load, most of the
+PCRE documentation describes the 8-bit library, with only occasional references
+to the 16-bit library. This page describes what is different when you use the
+16-bit library.
+
+
+WARNING: A single application can be linked with both libraries, but you must
+take care when processing any particular pattern to use functions from just one
+library. For example, if you want to study a pattern that was compiled with
+pcre16_compile(), you must do so with pcre16_study(), not
+pcre_study(), and you must free the study data with
+pcre16_free_study().
+
+There is only one header file, pcre.h. It contains prototypes for all the
+functions in both libraries, as well as definitions of flags, structures, error
+codes, etc.
+
+In Unix-like systems, the 16-bit library is called libpcre16, and can
+normally be accesss by adding -lpcre16 to the command for linking an
+application that uses PCRE.
+
+In the 8-bit library, strings are passed to PCRE library functions as vectors
+of bytes with the C type "char *". In the 16-bit library, strings are passed as
+vectors of unsigned 16-bit quantities. The macro PCRE_UCHAR16 specifies an
+appropriate data type, and PCRE_SPTR16 is defined as "const PCRE_UCHAR16 *". In
+very many environments, "short int" is a 16-bit data type. When PCRE is built,
+it defines PCRE_UCHAR16 as "short int", but checks that it really is a 16-bit
+data type. If it is not, the build fails with an error message telling the
+maintainer to modify the definition appropriately.
+
+The types of the opaque structures that are used for compiled 16-bit patterns
+and JIT stacks are pcre16 and pcre16_jit_stack respectively. The
+type of the user-accessible structure that is returned by pcre16_study()
+is pcre16_extra, and the type of the structure that is used for passing
+data to a callout function is pcre16_callout_block. These structures
+contain the same fields, with the same names, as their 8-bit counterparts. The
+only difference is that pointers to character strings are 16-bit instead of
+8-bit types.
+
+For every function in the 8-bit library there is a corresponding function in
+the 16-bit library with a name that starts with pcre16_ instead of
+pcre_. The prototypes are listed above. In addition, there is one extra
+function, pcre16_utf16_to_host_byte_order(). This is a utility function
+that converts a UTF-16 character string to host byte order if necessary. The
+other 16-bit functions expect the strings they are passed to be in host byte
+order.
+
+
+The input and output arguments of
+pcre16_utf16_to_host_byte_order() may point to the same address, that is,
+conversion in place is supported. The output buffer must be at least as long as
+the input.
+
+
+The length argument specifies the number of 16-bit data units in the
+input string; a negative value specifies a zero-terminated string.
+
+
+If byte_order is NULL, it is assumed that the string starts off in host
+byte order. This may be changed by byte-order marks (BOMs) anywhere in the
+string (commonly as the first character).
+
+
+If byte_order is not NULL, a non-zero value of the integer to which it
+points means that the input starts off in host byte order, otherwise the
+opposite order is assumed. Again, BOMs in the string can change this. The final
+byte order is passed back at the end of processing.
+
+
+If keep_boms is not zero, byte-order mark characters (0xfeff) are copied
+into the output string. Otherwise they are discarded.
+
+
+The result of the function is the number of 16-bit units placed into the output
+buffer, including the zero terminator if the string was zero-terminated.
+
+The name-to-number translation table that is maintained for named subpatterns
+uses 16-bit characters. The pcre16_get_stringtable_entries() function
+returns the length of each entry in the table as the number of 16-bit data
+units.
+
+There are two new general option names, PCRE_UTF16 and PCRE_NO_UTF16_CHECK,
+which correspond to PCRE_UTF8 and PCRE_NO_UTF8_CHECK in the 8-bit library. In
+fact, these new options define the same bits in the options word. There is a
+discussion about the
+validity of UTF-16 strings
+in the
+pcreunicode
+page.
+
+
+For the pcre16_config() function there is an option PCRE_CONFIG_UTF16
+that returns 1 if UTF-16 support is configured, otherwise 0. If this option is
+given to pcre_config(), or if the PCRE_CONFIG_UTF8 option is given to
+pcre16_config(), the result is the PCRE_ERROR_BADOPTION error.
+
+In 16-bit mode, when PCRE_UTF16 is not set, character values are treated in the
+same way as in 8-bit, non UTF-8 mode, except, of course, that they can range
+from 0 to 0xffff instead of 0 to 0xff. Character types for characters less than
+0xff can therefore be influenced by the locale in the same way as before.
+Characters greater than 0xff have only one case, and no "type" (such as letter
+or digit).
+
+
+In UTF-16 mode, the character code is Unicode, in the range 0 to 0x10ffff, with
+the exception of values in the range 0xd800 to 0xdfff because those are
+"surrogate" values that are used in pairs to encode values greater than 0xffff.
+
+
+A UTF-16 string can indicate its endianness by special code knows as a
+byte-order mark (BOM). The PCRE functions do not handle this, expecting strings
+to be in host byte order. A utility function called
+pcre16_utf16_to_host_byte_order() is provided to help with this (see
+above).
+
+The errors PCRE_ERROR_BADUTF16_OFFSET and PCRE_ERROR_SHORTUTF16 correspond to
+their 8-bit counterparts. The error PCRE_ERROR_BADMODE is given when a compiled
+pattern is passed to a function that processes patterns in the other
+mode, for example, if a pattern compiled with pcre_compile() is passed to
+pcre16_exec().
+
+
+There are new error codes whose names begin with PCRE_UTF16_ERR for invalid
+UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for UTF-8 strings that
+are described in the section entitled
+"Reason codes for invalid UTF-8 strings"
+in the main
+pcreapi
+page. The UTF-16 errors are:
+
+ PCRE_UTF16_ERR1 Missing low surrogate at end of string
+ PCRE_UTF16_ERR2 Invalid low surrogate follows high surrogate
+ PCRE_UTF16_ERR3 Isolated low surrogate
+ PCRE_UTF16_ERR4 Invalid character 0xfffe
+
+If there is an error while compiling a pattern, the error text that is passed
+back by pcre16_compile() or pcre16_compile2() is still an 8-bit
+character string, zero-terminated.
+
+The pcretest program continues to operate with 8-bit input and output
+files, but it can be used for testing the 16-bit library. If it is run with the
+command line option -16, patterns and subject strings are converted from
+8-bit to 16-bit before being passed to PCRE, and the 16-bit library functions
+are used instead of the 8-bit ones. Returned 16-bit strings are converted to
+8-bit for output. If the 8-bit library was not compiled, pcretest
+defaults to 16-bit and the -16 option is ignored.
+
+
+When PCRE is being built, the RunTest script that is called by "make
+check" uses the pcretest-C option to discover which of the 8-bit
+and 16-bit libraries has been built, and runs the tests appropriately.
+
+Not all the features of the 8-bit library are available with the 16-bit
+library. The C++ and POSIX wrapper functions support only the 8-bit library,
+and the pcregrep program is at present 8-bit only.
+
+This page is part of the PCRE HTML documentation. It was generated automatically
+from the original man page. If there is any nonsense in it, please consult the
+man page, in case the conversion went wrong.
+
+
+SYNOPSIS
+
+
+This function provides control over the memory used as a stack at run-time by a
+call to pcre[16]_exec() with a pattern that has been successfully
+compiled with JIT optimization. The arguments are:
+
+ extra the data pointer returned by pcre[16]_study()
+ callback a callback function
+ data a JIT stack or a value to be passed to the callback
+ function
+
+
+
+If callback is NULL and data is NULL, an internal 32K block on
+the machine stack is used.
+
+
+If callback is NULL and data is not NULL, data must
+be a valid JIT stack, the result of calling pcre[16]_jit_stack_alloc().
+
+
+If callback not NULL, it is called with data as an argument at
+the start of matching, in order to set up a JIT stack. If the result is NULL,
+the internal 32K stack is used; otherwise the return value must be a valid JIT
+stack, the result of calling pcre[16]_jit_stack_alloc().
+
+
+You may safely assign the same JIT stack to multiple patterns, as long as they
+are all matched in the same thread. In a multithread application, each thread
+must use its own JIT stack. For more details, see the
+pcrejit
+page.
+
+
+There is a complete description of the PCRE native API in the
+pcreapi
+page and a description of the POSIX API in the
+pcreposix
+page.
+
+pcre16 *pcre16_compile(PCRE_SPTR16 pattern, int options,
+const char **errptr, int *erroffset,
+const unsigned char *tableptr);
+
DESCRIPTION
This function compiles a regular expression into an internal form. It is the
-same as pcre_compile2(), except for the absence of the errorcodeptr
-argument. Its arguments are:
+same as pcre[16]_compile2(), except for the absence of the
+errorcodeptr argument. Its arguments are:
pattern A zero-terminated string containing the
regular expression to be compiled
@@ -49,7 +54,7 @@
PCRE_DOLLAR_ENDONLY $ not to match newline at end
PCRE_DOTALL . matches anything including NL
PCRE_DUPNAMES Allow duplicate names for subpatterns
- PCRE_EXTENDED Ignore whitespace and # comments
+ PCRE_EXTENDED Ignore white space and # comments
PCRE_EXTRA PCRE extra features
(not much use currently)
PCRE_FIRSTLINE Force matching to be before newline
@@ -63,15 +68,19 @@
PCRE_NEWLINE_LF Set LF as the newline sequence
PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren-
theses (named ones available)
+ PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16
+ validity (only relevant if
+ PCRE_UTF16 is set)
PCRE_NO_UTF8_CHECK Do not check the pattern for UTF-8
validity (only relevant if
PCRE_UTF8 is set)
PCRE_UCP Use Unicode properties for \d, \w, etc.
PCRE_UNGREEDY Invert greediness of quantifiers
- PCRE_UTF8 Run in UTF-8 mode
+ PCRE_UTF16 Run in pcre16_compile() UTF-16 mode
+ PCRE_UTF8 Run in pcre_compile() UTF-8 mode
-PCRE must be built with UTF-8 support in order to use PCRE_UTF8 and
-PCRE_NO_UTF8_CHECK, and with UCP support if PCRE_UCP is used.
+PCRE must be built with UTF support in order to use PCRE_UTF8/16 and
+PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used.
The yield of the function is a pointer to a private data structure that
diff -Nru pcre3-8.12/doc/html/pcre_compile2.html pcre3-8.31/doc/html/pcre_compile2.html
--- pcre3-8.12/doc/html/pcre_compile2.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_compile2.html 2012-07-06 09:55:27.000000000 +0000
@@ -24,13 +24,19 @@
const char **errptr, int *erroffset,const unsigned char *tableptr);
+
+pcre16 *pcre16_compile2(PCRE_SPTR16 pattern, int options,
+int *errorcodeptr,
+const char **errptr, int *erroffset,
+const unsigned char *tableptr);
+
DESCRIPTION
This function compiles a regular expression into an internal form. It is the
-same as pcre_compile(), except for the addition of the errorcodeptr
-argument. The arguments are:
+same as pcre[16]_compile(), except for the addition of the
+errorcodeptr argument. The arguments are:
pattern A zero-terminated string containing the
regular expression to be compiled
@@ -51,7 +57,7 @@
PCRE_DOLLAR_ENDONLY $ not to match newline at end
PCRE_DOTALL . matches anything including NL
PCRE_DUPNAMES Allow duplicate names for subpatterns
- PCRE_EXTENDED Ignore whitespace and # comments
+ PCRE_EXTENDED Ignore white space and # comments
PCRE_EXTRA PCRE extra features
(not much use currently)
PCRE_FIRSTLINE Force matching to be before newline
@@ -65,15 +71,19 @@
PCRE_NEWLINE_LF Set LF as the newline sequence
PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren-
theses (named ones available)
+ PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16
+ validity (only relevant if
+ PCRE_UTF16 is set)
PCRE_NO_UTF8_CHECK Do not check the pattern for UTF-8
validity (only relevant if
PCRE_UTF8 is set)
PCRE_UCP Use Unicode properties for \d, \w, etc.
PCRE_UNGREEDY Invert greediness of quantifiers
- PCRE_UTF8 Run in UTF-8 mode
+ PCRE_UTF16 Run pcre16_compile() in UTF-16 mode
+ PCRE_UTF8 Run pcre_compile() in UTF-8 mode
-PCRE must be built with UTF-8 support in order to use PCRE_UTF8 and
-PCRE_NO_UTF8_CHECK, and with UCP support if PCRE_UCP is used.
+PCRE must be built with UTF support in order to use PCRE_UTF8/16 and
+PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used.
The yield of the function is a pointer to a private data structure that
diff -Nru pcre3-8.12/doc/html/pcre_config.html pcre3-8.31/doc/html/pcre_config.html
--- pcre3-8.12/doc/html/pcre_config.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_config.html 2012-07-06 09:55:27.000000000 +0000
@@ -21,19 +21,29 @@
int pcre_config(int what, void *where);
+
+int pcre16_config(int what, void *where);
+
DESCRIPTION
This function makes it possible for a client program to find out which optional
-features are available in the version of the PCRE library it is using. Its
+features are available in the version of the PCRE library it is using. The
arguments are as follows:
what A code specifying what information is required
where Points to where to put the data
-The available codes are:
+The where argument must point to an integer variable, except for
+PCRE_CONFIG_MATCH_LIMIT and PCRE_CONFIG_MATCH_LIMIT_RECURSION, when it must
+point to an unsigned long integer. The available codes are:
+ PCRE_CONFIG_JIT Availability of just-in-time compiler
+ support (1=yes 0=no)
+ PCRE_CONFIG_JITTARGET String containing information about the
+ target architecture for the JIT compiler,
+ or NULL if there is no JIT support
PCRE_CONFIG_LINK_SIZE Internal link size: 2, 3, or 4
PCRE_CONFIG_MATCH_LIMIT Internal resource limit
PCRE_CONFIG_MATCH_LIMIT_RECURSION
@@ -48,16 +58,20 @@
0 all Unicode line endings
1 CR, LF, or CRLF only
PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
- Threshold of return slots, above
- which malloc() is used by
- the POSIX API
+ Threshold of return slots, above which
+ malloc() is used by the POSIX API
PCRE_CONFIG_STACKRECURSE Recursion implementation (1=stack 0=heap)
- PCRE_CONFIG_UTF8 Availability of UTF-8 support (1=yes 0=no)
+ PCRE_CONFIG_UTF16 Availability of UTF-16 support (1=yes
+ 0=no); option for pcre16_config()
+ PCRE_CONFIG_UTF8 Availability of UTF-8 support (1=yes 0=no);
+ option for pcre_config()
PCRE_CONFIG_UNICODE_PROPERTIES
Availability of Unicode property support
(1=yes 0=no)
-The function yields 0 on success or PCRE_ERROR_BADOPTION otherwise.
+The function yields 0 on success or PCRE_ERROR_BADOPTION otherwise. That error
+is also given if PCRE_CONFIG_UTF16 is passed to pcre_config() or if
+PCRE_CONFIG_UTF8 is passed to pcre16_config().
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcre_copy_named_substring.html pcre3-8.31/doc/html/pcre_copy_named_substring.html
--- pcre3-8.12/doc/html/pcre_copy_named_substring.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_copy_named_substring.html 2012-07-06 09:55:27.000000000 +0000
@@ -24,6 +24,12 @@
int stringcount, const char *stringname,char *buffer, int buffersize);
+
+int pcre16_copy_named_substring(const pcre16 *code,
+PCRE_SPTR16 subject, int *ovector,
+int stringcount, PCRE_SPTR16 stringname,
+PCRE_UCHAR16 *buffer, int buffersize);
+
DESCRIPTION
@@ -33,8 +39,8 @@
code Pattern that was successfully matched
subject Subject that has been successfully matched
- ovector Offset vector that pcre_exec() used
- stringcount Value returned by pcre_exec()
+ ovector Offset vector that pcre[16]_exec() used
+ stringcount Value returned by pcre[16]_exec()stringname Name of the required substring
buffer Buffer to receive the string
buffersize Size of buffer
diff -Nru pcre3-8.12/doc/html/pcre_copy_substring.html pcre3-8.31/doc/html/pcre_copy_substring.html
--- pcre3-8.12/doc/html/pcre_copy_substring.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_copy_substring.html 2012-07-06 09:55:27.000000000 +0000
@@ -23,6 +23,11 @@
int stringcount, int stringnumber, char *buffer,int buffersize);
+
+int pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector,
+int stringcount, int stringnumber, PCRE_UCHAR16 *buffer,
+int buffersize);
+
DESCRIPTION
@@ -31,8 +36,8 @@
buffer. The arguments are:
subject Subject that has been successfully matched
- ovector Offset vector that pcre_exec() used
- stringcount Value returned by pcre_exec()
+ ovector Offset vector that pcre[16]_exec() used
+ stringcount Value returned by pcre[16]_exec()stringnumber Number of the required substring
buffer Buffer to receive the string
buffersize Size of buffer
diff -Nru pcre3-8.12/doc/html/pcre_dfa_exec.html pcre3-8.31/doc/html/pcre_dfa_exec.html
--- pcre3-8.12/doc/html/pcre_dfa_exec.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_dfa_exec.html 2012-07-06 09:55:27.000000000 +0000
@@ -24,6 +24,12 @@
int options, int *ovector, int ovecsize,int *workspace, int wscount);
+
+int pcre16_dfa_exec(const pcre16 *code, const pcre16_extra *extra,
+PCRE_SPTR16 subject, int length, int startoffset,
+int options, int *ovector, int ovecsize,
+int *workspace, int wscount);
+
DESCRIPTION
@@ -31,10 +37,11 @@
This function matches a compiled regular expression against a given subject
string, using an alternative matching algorithm that scans the subject string
just once (not Perl-compatible). Note that the main, Perl-compatible,
-matching function is pcre_exec(). The arguments for this function are:
+matching function is pcre[16]_exec(). The arguments for this function
+are:
code Points to the compiled pattern
- extra Points to an associated pcre_extra structure,
+ extra Points to an associated pcre[16]_extra structure,
or is NULL
subject Points to the subject string
length Length of the subject string, in bytes
@@ -62,6 +69,9 @@
PCRE_NOTEMPTY_ATSTART An empty string at the start of the subject
is not a valid match
PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations
+ PCRE_NO_UTF16_CHECK Do not check the subject for UTF-16
+ validity (only relevant if PCRE_UTF16
+ was set at compile time)
PCRE_NO_UTF8_CHECK Do not check the subject for UTF-8
validity (only relevant if PCRE_UTF8
was set at compile time)
@@ -80,19 +90,23 @@
page.
-A pcre_extra structure contains the following fields:
+A pcre[16]_extra structure contains the following fields:
- flags Bits indicating which fields are set
- study_data Opaque data from pcre_study()
- match_limit Limit on internal resource use
+ flags Bits indicating which fields are set
+ study_data Opaque data from pcre[16]_study()
+ match_limit Limit on internal resource use
match_limit_recursion Limit on internal recursion depth
- callout_data Opaque data passed back to callouts
- tables Points to character tables or is NULL
+ callout_data Opaque data passed back to callouts
+ tables Points to character tables or is NULL
+ mark For passing back a *MARK pointer
+ executable_jit Opaque data from JIT compilation
The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT,
-PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, and
-PCRE_EXTRA_TABLES. For this matching function, the match_limit and
-match_limit_recursion fields are not used, and must not be set.
+PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA,
+PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT. For this
+matching function, the match_limit and match_limit_recursion fields
+are not used, and must not be set. The PCRE_EXTRA_EXECUTABLE_JIT flag and
+the corresponding variable are ignored.
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcre_exec.html pcre3-8.31/doc/html/pcre_exec.html
--- pcre3-8.12/doc/html/pcre_exec.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_exec.html 2012-07-06 09:55:27.000000000 +0000
@@ -23,6 +23,11 @@
const char *subject, int length, int startoffset,int options, int *ovector, int ovecsize);
+
+int pcre16_exec(const pcre16 *code, const pcre16_extra *extra,
+PCRE_SPTR16 subject, int length, int startoffset,
+int options, int *ovector, int ovecsize);
+
DESCRIPTION
@@ -32,7 +37,7 @@
offsets to captured substrings. Its arguments are:
code Points to the compiled pattern
- extra Points to an associated pcre_extra structure,
+ extra Points to an associated pcre[16]_extra structure,
or is NULL
subject Points to the subject string
length Length of the subject string, in bytes
@@ -58,6 +63,9 @@
PCRE_NOTEMPTY_ATSTART An empty string at the start of the subject
is not a valid match
PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations
+ PCRE_NO_UTF16_CHECK Do not check the subject for UTF-16
+ validity (only relevant if PCRE_UTF16
+ was set at compile time)
PCRE_NO_UTF8_CHECK Do not check the subject for UTF-8
validity (only relevant if PCRE_UTF8
was set at compile time)
@@ -70,16 +78,18 @@
pcrepartial
page. A pcre_extra structure contains the following fields:
- flags Bits indicating which fields are set
- study_data Opaque data from pcre_study()
- match_limit Limit on internal resource use
+ flags Bits indicating which fields are set
+ study_data Opaque data from pcre[16]_study()
+ match_limit Limit on internal resource use
match_limit_recursion Limit on internal recursion depth
- callout_data Opaque data passed back to callouts
- tables Points to character tables or is NULL
+ callout_data Opaque data passed back to callouts
+ tables Points to character tables or is NULL
+ mark For passing back a *MARK pointer
+ executable_jit Opaque data from JIT compilation
The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT,
-PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, and
-PCRE_EXTRA_TABLES.
+PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA,
+PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT.
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcre_free_study.html pcre3-8.31/doc/html/pcre_free_study.html
--- pcre3-8.12/doc/html/pcre_free_study.html 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_free_study.html 2012-07-06 09:55:27.000000000 +0000
@@ -0,0 +1,43 @@
+
+
+This page is part of the PCRE HTML documentation. It was generated automatically
+from the original man page. If there is any nonsense in it, please consult the
+man page, in case the conversion went wrong.
+
+
+SYNOPSIS
+
+
+#include <pcre.h>
+
+
+void pcre_free_study(pcre_extra *extra);
+
+
+void pcre16_free_study(pcre16_extra *extra);
+
+
+DESCRIPTION
+
+
+This function is used to free the memory used for the data generated by a call
+to pcre[16]_study() when it is no longer needed. The argument must be the
+result of such a call.
+
+
+There is a complete description of the PCRE native API in the
+pcreapi
+page and a description of the POSIX API in the
+pcreposix
+page.
+
This is a convenience function for freeing the store obtained by a previous
-call to pcre_get_substring() or pcre_get_named_substring(). Its
-only argument is a pointer to the string.
+call to pcre[16]_get_substring() or pcre[16]_get_named_substring().
+Its only argument is a pointer to the string.
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcre_free_substring_list.html pcre3-8.31/doc/html/pcre_free_substring_list.html
--- pcre3-8.12/doc/html/pcre_free_substring_list.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_free_substring_list.html 2012-07-06 09:55:27.000000000 +0000
@@ -21,13 +21,16 @@
This is a convenience function for freeing the store obtained by a previous
-call to pcre_get_substring_list(). Its only argument is a pointer to the
-list of string pointers.
+call to pcre[16]_get_substring_list(). Its only argument is a pointer to
+the list of string pointers.
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcre_fullinfo.html pcre3-8.31/doc/html/pcre_fullinfo.html
--- pcre3-8.12/doc/html/pcre_fullinfo.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_fullinfo.html 2012-07-06 09:55:27.000000000 +0000
@@ -22,6 +22,10 @@
int pcre_fullinfo(const pcre *code, const pcre_extra *extra,int what, void *where);
DESCRIPTION
@@ -29,7 +33,7 @@
This function returns information about a compiled pattern. Its arguments are:
code Compiled regular expression
- extra Result of pcre_study() or NULL
+ extra Result of pcre[16]_study() or NULL
what What information is required
where Where to put the information
@@ -38,13 +42,16 @@
PCRE_INFO_BACKREFMAX Number of highest back reference
PCRE_INFO_CAPTURECOUNT Number of capturing subpatterns
PCRE_INFO_DEFAULT_TABLES Pointer to default tables
- PCRE_INFO_FIRSTBYTE Fixed first byte for a match, or
+ PCRE_INFO_FIRSTBYTE Fixed first data unit for a match, or
-1 for start of string
or after newline, or
-2 otherwise
- PCRE_INFO_FIRSTTABLE Table of first bytes (after studying)
+ PCRE_INFO_FIRSTTABLE Table of first data units (after studying)
+ PCRE_INFO_HASCRORLF Return 1 if explicit CR or LF matches exist
PCRE_INFO_JCHANGED Return 1 if (?J) or (?-J) was used
- PCRE_INFO_LASTLITERAL Literal last byte required
+ PCRE_INFO_JIT Return 1 after successful JIT compilation
+ PCRE_INFO_JITSIZE Size of JIT compiled code
+ PCRE_INFO_LASTLITERAL Literal last data unit required
PCRE_INFO_MINLENGTH Lower bound length of matching strings
PCRE_INFO_NAMECOUNT Number of named subpatterns
PCRE_INFO_NAMEENTRYSIZE Size of name table entry
@@ -55,6 +62,16 @@
PCRE_INFO_SIZE Size of compiled pattern
PCRE_INFO_STUDYSIZE Size of study data
+The where argument must point to an integer variable, except for the
+following what values:
+
code Compiled pattern
subject Subject that has been successfully matched
- ovector Offset vector that pcre_exec() used
- stringcount Value returned by pcre_exec()
+ ovector Offset vector that pcre[16]_exec() used
+ stringcount Value returned by pcre[16]_exec()stringname Name of the required substring
stringptr Where to put the string pointer
The memory in which the substring is placed is obtained by calling
-pcre_malloc(). The convenience function pcre_free_substring() can
-be used to free it when it is no longer needed. The yield of the function is
-the length of the extracted substring, PCRE_ERROR_NOMEMORY if sufficient memory
-could not be obtained, or PCRE_ERROR_NOSUBSTRING if the string name is invalid.
+pcre[16]_malloc(). The convenience function
+pcre[16]_free_substring() can be used to free it when it is no longer
+needed. The yield of the function is the length of the extracted substring,
+PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or
+PCRE_ERROR_NOSUBSTRING if the string name is invalid.
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcre_get_stringnumber.html pcre3-8.31/doc/html/pcre_get_stringnumber.html
--- pcre3-8.12/doc/html/pcre_get_stringnumber.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_get_stringnumber.html 2012-07-06 09:55:27.000000000 +0000
@@ -22,6 +22,10 @@
int pcre_get_stringnumber(const pcre *code,const char *name);
DESCRIPTION
@@ -35,8 +39,8 @@
The yield of the function is the number of the parenthesis if the name is
found, or PCRE_ERROR_NOSUBSTRING otherwise. When duplicate names are allowed
(PCRE_DUPNAMES is set), it is not defined which of the numbers is returned by
-pcre_get_stringnumber(). You can obtain the complete list by calling
-pcre_get_stringtable_entries().
+pcre[16]_get_stringnumber(). You can obtain the complete list by calling
+pcre[16]_get_stringtable_entries().
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcre_get_stringtable_entries.html pcre3-8.31/doc/html/pcre_get_stringtable_entries.html
--- pcre3-8.12/doc/html/pcre_get_stringtable_entries.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_get_stringtable_entries.html 2012-07-06 09:55:27.000000000 +0000
@@ -22,6 +22,10 @@
int pcre_get_stringtable_entries(const pcre *code,const char *name, char **first, char **last);
DESCRIPTION
@@ -29,7 +33,7 @@
This convenience function finds, for a compiled pattern, the first and last
entries for a given name in the table that translates capturing parenthesis
names into numbers. When names are required to be unique (PCRE_DUPNAMES is
-not set), it is usually easier to use pcre_get_stringnumber()
+not set), it is usually easier to use pcre[16]_get_stringnumber()
instead.
+int pcre16_get_substring(PCRE_SPTR16 subject, int *ovector,
+int stringcount, int stringnumber,
+PCRE_SPTR16 *stringptr);
+
DESCRIPTION
@@ -31,16 +36,17 @@
arguments are:
subject Subject that has been successfully matched
- ovector Offset vector that pcre_exec() used
- stringcount Value returned by pcre_exec()
+ ovector Offset vector that pcre[16]_exec() used
+ stringcount Value returned by pcre[16]_exec()stringnumber Number of the required substring
stringptr Where to put the string pointer
The memory in which the substring is placed is obtained by calling
-pcre_malloc(). The convenience function pcre_free_substring() can
-be used to free it when it is no longer needed. The yield of the function is
-the length of the substring, PCRE_ERROR_NOMEMORY if sufficient memory could not
-be obtained, or PCRE_ERROR_NOSUBSTRING if the string number is invalid.
+pcre[16]_malloc(). The convenience function
+pcre[16]_free_substring() can be used to free it when it is no longer
+needed. The yield of the function is the length of the substring,
+PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or
+PCRE_ERROR_NOSUBSTRING if the string number is invalid.
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcre_get_substring_list.html pcre3-8.31/doc/html/pcre_get_substring_list.html
--- pcre3-8.12/doc/html/pcre_get_substring_list.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_get_substring_list.html 2012-07-06 09:55:27.000000000 +0000
@@ -22,6 +22,10 @@
int pcre_get_substring_list(const char *subject,int *ovector, int stringcount, const char ***listptr);
+
+int pcre16_get_substring_list(PCRE_SPTR16 subject,
+int *ovector, int stringcount, PCRE_SPTR16 **listptr);
+
DESCRIPTION
@@ -30,17 +34,17 @@
substrings. The arguments are:
subject Subject that has been successfully matched
- ovector Offset vector that pcre_exec used
- stringcount Value returned by pcre_exec
+ ovector Offset vector that pcre[16]_exec used
+ stringcount Value returned by pcre[16]_execlistptr Where to put a pointer to the list
The memory in which the substrings and the list are placed is obtained by
-calling pcre_malloc(). The convenience function
-pcre_free_substring_list() can be used to free it when it is no longer
-needed. A pointer to a list of pointers is put in the variable whose address is
-in listptr. The list is terminated by a NULL pointer. The yield of the
-function is zero on success or PCRE_ERROR_NOMEMORY if sufficient memory could
-not be obtained.
+calling pcre[16]_malloc(). The convenience function
+pcre[16]_free_substring_list() can be used to free it when it is no
+longer needed. A pointer to a list of pointers is put in the variable whose
+address is in listptr. The list is terminated by a NULL pointer. The
+yield of the function is zero on success or PCRE_ERROR_NOMEMORY if sufficient
+memory could not be obtained.
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcre_info.html pcre3-8.31/doc/html/pcre_info.html
--- pcre3-8.12/doc/html/pcre_info.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_info.html 1970-01-01 00:00:00.000000000 +0000
@@ -1,39 +0,0 @@
-
-
-This page is part of the PCRE HTML documentation. It was generated automatically
-from the original man page. If there is any nonsense in it, please consult the
-man page, in case the conversion went wrong.
-
-
-SYNOPSIS
-
-
-#include <pcre.h>
-
-
-int pcre_info(const pcre *code, int *optptr, int
-*firstcharptr);
-
-
-DESCRIPTION
-
-
-This function is obsolete. You should be using pcre_fullinfo() instead.
-
-
-There is a complete description of the PCRE native API in the
-pcreapi
-page and a description of the POSIX API in the
-pcreposix
-page.
-
+This page is part of the PCRE HTML documentation. It was generated automatically
+from the original man page. If there is any nonsense in it, please consult the
+man page, in case the conversion went wrong.
+
+
+SYNOPSIS
+
+
+This function is used to create a stack for use by the code compiled by the JIT
+optimization of pcre[16]_study(). The arguments are a starting size for
+the stack, and a maximum size to which it is allowed to grow. The result can be
+passed to the JIT run-time code by pcre[16]_assign_jit_stack(), or that
+function can set up a callback for obtaining a stack. A maximum stack size of
+512K to 1M should be more than enough for any pattern. For more details, see
+the
+pcrejit
+page.
+
+
+There is a complete description of the PCRE native API in the
+pcreapi
+page and a description of the POSIX API in the
+pcreposix
+page.
+
+This page is part of the PCRE HTML documentation. It was generated automatically
+from the original man page. If there is any nonsense in it, please consult the
+man page, in case the conversion went wrong.
+
+
+SYNOPSIS
+
+
+This function is used to free a JIT stack that was created by
+pcre[16]_jit_stack_alloc() when it is no longer needed. For more details,
+see the
+pcrejit
+page.
+
+
+There is a complete description of the PCRE native API in the
+pcreapi
+page and a description of the POSIX API in the
+pcreposix
+page.
+
This function builds a set of character tables for character values less than
-256. These can be passed to pcre_compile() to override PCRE's internal,
-built-in tables (which were made by pcre_maketables() when PCRE was
-compiled). You might want to do this if you are using a non-standard locale.
-The function yields a pointer to the tables.
+256. These can be passed to pcre[16]_compile() to override PCRE's
+internal, built-in tables (which were made by pcre[16]_maketables() when
+PCRE was compiled). You might want to do this if you are using a non-standard
+locale. The function yields a pointer to the tables.
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcre_pattern_to_host_byte_order.html pcre3-8.31/doc/html/pcre_pattern_to_host_byte_order.html
--- pcre3-8.12/doc/html/pcre_pattern_to_host_byte_order.html 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_pattern_to_host_byte_order.html 2012-07-06 09:55:27.000000000 +0000
@@ -0,0 +1,54 @@
+
+
+This page is part of the PCRE HTML documentation. It was generated automatically
+from the original man page. If there is any nonsense in it, please consult the
+man page, in case the conversion went wrong.
+
+
+SYNOPSIS
+
+
+This function ensures that the bytes in 2-byte and 4-byte values in a compiled
+pattern are in the correct order for the current host. It is useful when a
+pattern that has been compiled on one host is transferred to another that might
+have different endianness. The arguments are:
+
+ code A compiled regular expression
+ extra Points to an associated pcre[16]_extra structure,
+ or is NULL
+ tables Pointer to character tables, or NULL to
+ set the built-in default
+
+The result is 0 for success, a negative PCRE_ERROR_xxx value otherwise.
+
+
+There is a complete description of the PCRE native API in the
+pcreapi
+page and a description of the POSIX API in the
+pcreposix
+page.
+
+pcre16_extra *pcre16_study(const pcre16 *code, int options,
+const char **errptr);
+
DESCRIPTION
@@ -30,11 +34,12 @@
be extracted that might speed up matching. Its arguments are:
code A compiled regular expression
- options Options for pcre_study()
+ options Options for pcre[16]_study()errptr Where to put an error message
If the function succeeds, it returns a value that can be passed to
-pcre_exec() via its extra argument.
+pcre[16]_exec() or pcre[16]_dfa_exec() via their extra
+arguments.
If the function returns NULL, either it could not find any additional
@@ -42,8 +47,11 @@
the error value. It is NULL in first case.
-There are currently no options defined; the value of the second argument should
-always be zero.
+The only option is PCRE_STUDY_JIT_COMPILE. It requests just-in-time compilation
+if possible. If PCRE has been compiled without JIT support, this option is
+ignored. See the
+pcrejit
+page for further details.
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcre_utf16_to_host_byte_order.html pcre3-8.31/doc/html/pcre_utf16_to_host_byte_order.html
--- pcre3-8.12/doc/html/pcre_utf16_to_host_byte_order.html 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/html/pcre_utf16_to_host_byte_order.html 2012-07-06 09:55:27.000000000 +0000
@@ -0,0 +1,57 @@
+
+
+This page is part of the PCRE HTML documentation. It was generated automatically
+from the original man page. If there is any nonsense in it, please consult the
+man page, in case the conversion went wrong.
+
+
+SYNOPSIS
+
+
+#include <pcre.h>
+
+
+int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output,
+PCRE_SPTR16 input, int length, int *host_byte_order,
+int keep_boms);
+
+
+DESCRIPTION
+
+
+This function, which exists only in the 16-bit library, converts a UTF-16
+string to the correct order for the current host, taking account of any byte
+order marks (BOMs) within the string. Its arguments are:
+
+ output pointer to output buffer, may be the same as input
+ input pointer to input buffer
+ length number of 16-bit units in the input, or negative for
+ a zero-terminated string
+ host_byte_order a NULL value or a non-zero value pointed to means
+ start in host byte order
+ keep_boms if non-zero, BOMs are copied to the output string
+
+The result of the function is the number of 16-bit units placed into the output
+buffer, including the zero terminator if the string was zero-terminated.
+
+
+If host_byte_order is not NULL, it is set to indicate the byte order that
+is current at the end of the string.
+
+
+There is a complete description of the PCRE native API in the
+pcreapi
+page and a description of the POSIX API in the
+pcreposix
+page.
+
-This function returns a character string that gives the version number of the
-PCRE library and the date of its release.
+This function (even in the 16-bit library) returns a zero-terminated, 8-bit
+character string that gives the version number of the PCRE library and the date
+of its release.
There is a complete description of the PCRE native API in the
diff -Nru pcre3-8.12/doc/html/pcreapi.html pcre3-8.31/doc/html/pcreapi.html
--- pcre3-8.12/doc/html/pcreapi.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcreapi.html 2012-07-06 09:55:27.000000000 +0000
@@ -13,33 +13,37 @@
man page, in case the conversion went wrong.
pcre *pcre_compile(const char *pattern, int options,const char **errptr, int *erroffset,
@@ -56,6 +60,9 @@
const char **errptr);
+void pcre_free_study(pcre_extra *extra);
+
+
int pcre_exec(const pcre *code, const pcre_extra *extra,const char *subject, int length, int startoffset,int options, int *ovector, int ovecsize);
@@ -66,6 +73,7 @@
int options, int *ovector, int ovecsize,int *workspace, int wscount);
+From release 8.30, PCRE can be compiled as a library for handling 16-bit
+character strings as well as, or instead of, the original library that handles
+8-bit character strings. To avoid too much complication, this document
+describes the 8-bit versions of the functions, with only occasional references
+to the 16-bit library.
+
+
+The 16-bit functions operate in the same way as their 8-bit counterparts; they
+just use different data types for their arguments and results, and their names
+start with pcre16_ instead of pcre_. For every option that has UTF8
+in its name (for example, PCRE_UTF8), there is a corresponding 16-bit name with
+UTF8 replaced by UTF16. This facility is in fact just cosmetic; the 16-bit
+option names define the same bit values.
+
+
+References to bytes and UTF-8 in this document should be read as references to
+16-bit data quantities and UTF-16 when using the 16-bit library, unless
+specified otherwise. More details of the specific differences for the 16-bit
+library are given in the
+pcre16
+page.
+
PCRE has its own native API, which is described in this document. There are
-also some wrapper functions that correspond to the POSIX regular expression
-API. These are described in the
+also some wrapper functions (for the 8-bit library only) that correspond to the
+POSIX regular expression API, but they do not give access to all the
+functionality. They are described in the
pcreposix
documentation. Both of these APIs define a set of C function calls. A C++
-wrapper is distributed with PCRE. It is documented in the
+wrapper (again for the 8-bit library only) is also distributed with PCRE. It is
+documented in the
pcrecpp
page.
The native API C function prototypes are defined in the header file
-pcre.h, and on Unix systems the library itself is called libpcre.
-It can normally be accessed by adding -lpcre to the command for linking
-an application that uses PCRE. The header file defines the macros PCRE_MAJOR
-and PCRE_MINOR to contain the major and minor release numbers for the library.
-Applications can use these to include support for different releases of PCRE.
+pcre.h, and on Unix-like systems the (8-bit) library itself is called
+libpcre. It can normally be accessed by adding -lpcre to the
+command for linking an application that uses PCRE. The header file defines the
+macros PCRE_MAJOR and PCRE_MINOR to contain the major and minor release numbers
+for the library. Applications can use these to include support for different
+releases of PCRE.
In a Windows environment, if you want to statically link an application program
@@ -179,6 +226,18 @@
documentation describes how to compile and run it.
+Just-in-time compiler support is an optional feature of PCRE that can be built
+in appropriate hardware environments. It greatly speeds up the matching
+performance of many patterns. Simple programs can easily request that it be
+used if available, by setting an option that is ignored when it is not
+relevant. More complicated programs might need to make use of the functions
+pcre_jit_stack_alloc(), pcre_jit_stack_free(), and
+pcre_assign_jit_stack() in order to control the JIT code's memory usage.
+These functions are discussed in the
+pcrejit
+documentation.
+
+
A second matching function, pcre_dfa_exec(), which is not
Perl-compatible, is also provided. This uses a different algorithm for the
matching. The alternative algorithm finds all possible matches (at a given
@@ -214,10 +273,8 @@
The function pcre_fullinfo() is used to find out information about a
-compiled pattern; pcre_info() is an obsolete version that returns only
-some of the available information, but is retained for backwards compatibility.
-The function pcre_version() returns a pointer to a string containing the
-version of PCRE and its date of release.
+compiled pattern. The function pcre_version() returns a pointer to a
+string containing the version of PCRE and its date of release.
The function pcre_refcount() maintains a reference count in a data block
@@ -254,13 +311,13 @@
pcrecallout
documentation.
PCRE supports five different conventions for indicating line breaks in
strings: a single CR (carriage return) character, a single LF (linefeed)
character, the two-character sequence CRLF, any of the three preceding, or any
Unicode newline sequence. The Unicode newline sequences are the three just
-mentioned, plus the single characters VT (vertical tab, U+000B), FF (formfeed,
+mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed,
U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS
(paragraph separator, U+2029).
@@ -293,7 +350,7 @@
the \n or \r escape sequences, nor does it affect what \R matches, which is
controlled in a similar way, but by separate options.
- MULTITHREADING
+ MULTITHREADING
The PCRE functions can be used in multi-threading applications, with the
proviso that the memory management functions pointed to by pcre_malloc,
@@ -304,17 +361,24 @@
The compiled form of a regular expression is not altered during matching, so
the same compiled pattern can safely be used by several threads at once.
+If the just-in-time optimization feature is being used, it needs separate
+memory stack areas for each thread. See the
+pcrejit
+documentation for more details.
+
The compiled form of a regular expression can be saved and re-used at a later
time, possibly by a different program, and even on a host other than the one on
which it was compiled. Details are given in the
pcreprecompile
-documentation. However, compiling a regular expression with one version of PCRE
-for use with a different version is not guaranteed to work and may cause
-crashes.
+documentation, which includes a description of the
+pcre_pattern_to_host_byte_order() function. However, compiling a regular
+expression with one version of PCRE for use with a different version is not
+guaranteed to work and may cause crashes.
The first argument for pcre_config() is an integer, specifying which
information is required; the second argument is a pointer to a variable into
-which the information is placed. The following information is available:
+which the information is placed. The returned value is zero on success, or the
+negative error code PCRE_ERROR_BADOPTION if the value in the first argument is
+not recognized. The following information is available:
PCRE_CONFIG_UTF8
The output is an integer that is set to one if UTF-8 support is available;
-otherwise it is set to zero.
+otherwise it is set to zero. If this option is given to the 16-bit version of
+this function, pcre16_config(), the result is PCRE_ERROR_BADOPTION.
+
+ PCRE_CONFIG_UTF16
+
+The output is an integer that is set to one if UTF-16 support is available;
+otherwise it is set to zero. This value should normally be given to the 16-bit
+version of this function, pcre16_config(). If it is given to the 8-bit
+version of this function, the result is PCRE_ERROR_BADOPTION.
PCRE_CONFIG_UNICODE_PROPERTIES
The output is an integer that is set to one if support for Unicode character
properties is available; otherwise it is set to zero.
+ PCRE_CONFIG_JIT
+
+The output is an integer that is set to one if support for just-in-time
+compiling is available; otherwise it is set to zero.
+
+ PCRE_CONFIG_JITTARGET
+
+The output is a pointer to a zero-terminated "const char *" string. If JIT
+support is available, the string contains the name of the architecture for
+which the JIT compiler is configured, for example "x86 32bit (little endian +
+unaligned)". If JIT support is not available, the result is NULL.
+
PCRE_CONFIG_NEWLINE
The output is an integer whose value specifies the default character sequence
@@ -358,10 +444,12 @@
PCRE_CONFIG_LINK_SIZE
The output is an integer that contains the number of bytes used for internal
-linkage in compiled regular expressions. The value is 2, 3, or 4. Larger values
-allow larger regular expressions to be compiled, at the expense of slower
-matching. The default value of 2 is sufficient for all but the most massive
-patterns, since it allows the compiled pattern to be up to 64K in size.
+linkage in compiled regular expressions. For the 8-bit library, the value can
+be 2, 3, or 4. For the 16-bit library, the value is either 2 or 4 and is still
+a number of bytes. The default value of 2 is sufficient for all but the most
+massive patterns, since it allows the compiled pattern to be up to 64K in size.
+Larger values allow larger regular expressions to be compiled, at the expense
+of slower matching.
PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
@@ -393,7 +481,7 @@
pcre_stack_free are called to manage memory blocks on the heap, thus
avoiding the use of the stack.
- COMPILING A PATTERN
+ COMPILING A PATTERN
pcre *pcre_compile(const char *pattern, int options,const char **errptr, int *erroffset,
@@ -436,7 +524,7 @@
the pattern, the contents of the options argument specifies their
settings at the start of compilation and execution. The PCRE_ANCHORED,
PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and
-PCRE_NO_START_OPT options can be set at the time of matching as well as at
+PCRE_NO_START_OPTIMIZE options can be set at the time of matching as well as at
compile time.
@@ -444,17 +532,17 @@
Otherwise, if compilation of a pattern fails, pcre_compile() returns
NULL, and sets the variable pointed to by errptr to point to a textual
error message. This is a static string that is part of the library. You must
-not try to free it. The offset from the start of the pattern to the byte that
-was being processed when the error was discovered is placed in the variable
-pointed to by erroffset, which must not be NULL. If it is, an immediate
-error is given. Some errors are not detected until checks are carried out when
-the whole pattern has been scanned; in this case the offset is set to the end
-of the pattern.
+not try to free it. Normally, the offset from the start of the pattern to the
+byte that was being processed when the error was discovered is placed in the
+variable pointed to by erroffset, which must not be NULL (if it is, an
+immediate error is given). However, for an invalid UTF-8 string, the offset is
+that of the first byte of the failing character.
-Note that the offset is in bytes, not characters, even in UTF-8 mode. It may
-point into the middle of a UTF-8 character (for example, when
-PCRE_ERROR_BADUTF8 is returned for an invalid UTF-8 string).
+Some errors are not detected until the whole pattern has been scanned; in these
+cases, the offset passed back is the length of the pattern. Note that the
+offset is in bytes, not characters, even in UTF-8 mode. It may sometimes point
+into the middle of a UTF-8 character.
If pcre_compile2() is used instead of pcre_compile(), and the
@@ -553,17 +641,17 @@
PCRE_EXTENDED
-If this bit is set, whitespace data characters in the pattern are totally
-ignored except when escaped or inside a character class. Whitespace does not
+If this bit is set, white space data characters in the pattern are totally
+ignored except when escaped or inside a character class. White space does not
include the VT character (code 11). In addition, characters between an
unescaped # outside a character class and the next newline, inclusive, are also
ignored. This is equivalent to Perl's /x option, and it can be changed within a
pattern by a (?x) option setting.
-Which characters are interpreted as newlines
-is controlled by the options passed to pcre_compile() or by a special
-sequence at the start of the pattern, as described in the section entitled
+Which characters are interpreted as newlines is controlled by the options
+passed to pcre_compile() or by a special sequence at the start of the
+pattern, as described in the section entitled
"Newline conventions"
in the pcrepattern documentation. Note that the end of this type of
comment is a literal newline sequence in the pattern; escape sequences that
@@ -571,7 +659,7 @@
This option makes it possible to include comments inside complicated patterns.
-Note, however, that this applies only to data characters. Whitespace characters
+Note, however, that this applies only to data characters. White space characters
may never appear within special character sequences in a pattern, for example
within the sequence (?( that introduces a conditional subpattern.
@@ -608,6 +696,23 @@
string (by default this causes the current matching alternative to fail). A
pattern such as (\1)(a) succeeds when this option is set (assuming it can find
an "a" in the subject), whereas it fails by default, for Perl compatibility.
+
+
+(3) \U matches an upper case "U" character; by default \U causes a compile
+time error (Perl uses \U to upper case subsequent characters).
+
+
+(4) \u matches a lower case "u" character unless it is followed by four
+hexadecimal digits, in which case the hexadecimal number defines the code point
+to match. By default, \u causes a compile time error (Perl uses it to upper
+case the following character).
+
+
+(5) \x matches a lower case "x" character unless it is followed by two
+hexadecimal digits, in which case the hexadecimal number defines the code point
+to match. By default, as in Perl, a hexadecimal number is always expected after
+\x, but it may have zero, one, or two digits (so, for example, \xz matches a
+binary zero character followed by z).
PCRE_MULTILINE
@@ -640,9 +745,9 @@
preceding sequences should be recognized. Setting PCRE_NEWLINE_ANY specifies
that any Unicode newline sequence should be recognized. The Unicode newline
sequences are the three just mentioned, plus the single characters VT (vertical
-tab, U+000B), FF (formfeed, U+000C), NEL (next line, U+0085), LS (line
-separator, U+2028), and PS (paragraph separator, U+2029). The last two are
-recognized only in UTF-8 mode.
+tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line
+separator, U+2028), and PS (paragraph separator, U+2029). For the 8-bit
+library, the last two are recognized only in UTF-8 mode.
The newline setting in the options word uses three bits that are treated
@@ -654,7 +759,7 @@
The only time that a line break in a pattern is specially recognized when
-compiling is when PCRE_EXTENDED is set. CR and LF are whitespace characters,
+compiling is when PCRE_EXTENDED is set. CR and LF are white space characters,
and so are ignored in this mode. Also, an unescaped # outside a character class
indicates a comment that lasts until after the next line break sequence. In
other circumstances, line break sequences in patterns are treated as literal
@@ -702,36 +807,35 @@
PCRE_UTF8
This option causes PCRE to regard both the pattern and the subject as strings
-of UTF-8 characters instead of single-byte character strings. However, it is
-available only when PCRE is built to include UTF-8 support. If not, the use
-of this option provokes an error. Details of how this option changes the
-behaviour of PCRE are given in the
-section on UTF-8 support
-in the main
-pcre
+of UTF-8 characters instead of single-byte strings. However, it is available
+only when PCRE is built to include UTF support. If not, the use of this option
+provokes an error. Details of how this option changes the behaviour of PCRE are
+given in the
+pcreunicode
page.
PCRE_NO_UTF8_CHECK
-When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is
-automatically checked. There is a discussion about the
-validity of UTF-8 strings
-in the main
-pcre
-page. If an invalid UTF-8 sequence of bytes is found, pcre_compile()
-returns an error. If you already know that your pattern is valid, and you want
-to skip this check for performance reasons, you can set the PCRE_NO_UTF8_CHECK
-option. When it is set, the effect of passing an invalid UTF-8 string as a
-pattern is undefined. It may cause your program to crash. Note that this option
-can also be passed to pcre_exec() and pcre_dfa_exec(), to suppress
-the UTF-8 validity checking of subject strings.
+When PCRE_UTF8 is set, the validity of the pattern as a UTF-8
+string is automatically checked. There is a discussion about the
+validity of UTF-8 strings
+in the
+pcreunicode
+page. If an invalid UTF-8 sequence is found, pcre_compile() returns an
+error. If you already know that your pattern is valid, and you want to skip
+this check for performance reasons, you can set the PCRE_NO_UTF8_CHECK option.
+When it is set, the effect of passing an invalid UTF-8 string as a pattern is
+undefined. It may cause your program to crash. Note that this option can also
+be passed to pcre_exec() and pcre_dfa_exec(), to suppress the
+validity checking of subject strings.
- COMPILATION ERROR CODES
+ COMPILATION ERROR CODES
The following table lists the error codes than may be returned by
pcre_compile2(), along with the error messages that may be returned by
-both compiling functions. As PCRE has developed, some error codes have fallen
-out of use. To avoid confusion, they have not been re-used.
+both compiling functions. Note that error messages are always 8-bit ASCII
+strings, even in 16-bit mode. As PCRE has developed, some error codes have
+fallen out of use. To avoid confusion, they have not been re-used.
0 no error
1 \ at end of pattern
@@ -765,26 +869,26 @@
29 (?R or (?[+-]digits must be followed by )
30 unknown POSIX class name
31 POSIX collating elements are not supported
- 32 this version of PCRE is not compiled with PCRE_UTF8 support
+ 32 this version of PCRE is compiled without UTF support
33 [this code is not in use]
34 character value in \x{...} sequence is too large
35 invalid condition (?(0)
36 \C not allowed in lookbehind assertion
- 37 PCRE does not support \L, \l, \N, \U, or \u
+ 37 PCRE does not support \L, \l, \N{name}, \U, or \u
38 number after (?C is > 255
39 closing ) for (?C expected
40 recursive call could loop indefinitely
41 unrecognized character after (?P
42 syntax error in subpattern name (missing terminator)
43 two named subpatterns have the same name
- 44 invalid UTF-8 string
+ 44 invalid UTF-8 string (specifically UTF-8)
45 support for \P, \p, and \X has not been compiled
46 malformed \P or \p sequence
47 unknown property name after \P or \p
48 subpattern name is too long (maximum 32 characters)
49 too many named subpatterns (maximum 10000)
50 [this code is not in use]
- 51 octal value is greater than \377 (not in UTF-8 mode)
+ 51 octal value is greater than \377 in 8-bit non-UTF-8 mode
52 internal error: overran compiling workspace
53 internal error: previously-checked referenced subpattern
not found
@@ -803,12 +907,22 @@
65 different names for subpatterns of the same number are
not allowed
66 (*MARK) must have an argument
- 67 this version of PCRE is not compiled with PCRE_UCP support
+ 67 this version of PCRE is not compiled with Unicode property
+ support
+ 68 \c must be followed by an ASCII character
+ 69 \k is not followed by a braced, angle-bracketed, or quoted name
+ 70 internal error: unknown opcode in find_fixedlength()
+ 71 \N is not supported in a class
+ 72 too many forward references
+ 73 disallowed Unicode code point (>= 0xd800 && <= 0xdfff)
+ 74 invalid UTF-16 string (specifically UTF-16)
+ 75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
+ 76 character value in \u.... sequence is too large
The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may
be used if the limits were changed when PCRE was built.
-
- STUDYING A PATTERN
+
+ STUDYING A PATTERN
pcre_extra *pcre_study(const pcre *code, int optionsconst char **errptr);
@@ -837,8 +951,28 @@
pcre_dfa_exec(), it must set up its own pcre_extra block.
-The second argument of pcre_study() contains option bits. At present, no
-options are defined, and this argument should always be zero.
+The second argument of pcre_study() contains option bits. There are three
+options:
+
+If any of these are set, and the just-in-time compiler is available, the
+pattern is further compiled into machine code that executes much faster than
+the pcre_exec() interpretive matching function. If the just-in-time
+compiler is not available, these options are ignored. All other bits in the
+options argument must be zero.
+
+
+JIT compilation is a heavyweight optimization. It can take some time for
+patterns to be analyzed, and for one-off matches and simple patterns the
+benefit of faster execution might be offset by a much slower study time.
+Not all patterns can be optimized by the JIT compiler. For those that cannot be
+handled, matching automatically falls back to the pcre_exec()
+interpreter. For more details, see the
+pcrejit
+documentation.
The third argument for pcre_study() is a pointer for an error message. If
@@ -849,13 +983,30 @@
sure that it has run successfully.
-This is a typical call to pcre_study():
+When you are finished with a pattern, you can free the memory used for the
+study data by calling pcre_free_study(). This function was added to the
+API for release 8.20. For earlier versions, the memory could be freed with
+pcre_free(), just like the pattern itself. This will still work in cases
+where JIT optimization is not used, but it is advisable to change to the new
+function when convenient.
+
+
+This is a typical way in which pcre_study() is used (except that in a
+real application there should be tests for errors):
- pcre_extra *pe;
- pe = pcre_study(
+ int rc;
+ pcre *re;
+ pcre_extra *sd;
+ re = pcre_compile("pattern", 0, &error, &erroroffset, NULL);
+ sd = pcre_study(
re, /* result of pcre_compile() */
- 0, /* no options exist */
+ 0, /* no options */
&error); /* set to NULL or points to a message */
+ rc = pcre_exec( /* see below for details of pcre_exec() options */
+ re, sd, "subject", 7, 0, 0, ovector, 30);
+ ...
+ pcre_free_study(sd);
+ pcre_free(re);
Studying a pattern does two things: first, a lower bound for the length of
subject string that is needed to match the pattern is computed. This does not
@@ -869,28 +1020,31 @@
Studying a pattern is also useful for non-anchored patterns that do not have a
single fixed starting character. A bitmap of possible starting bytes is
created. This speeds up finding a position in the subject at which to start
-matching.
+matching. (In 16-bit mode, the bitmap is used for 16-bit values less than 256.)
-The two optimizations just described can be disabled by setting the
-PCRE_NO_START_OPTIMIZE option when calling pcre_exec() or
-pcre_dfa_exec(). You might want to do this if your pattern contains
-callouts or (*MARK), and you want to make use of these facilities in cases
-where matching fails. See the discussion of PCRE_NO_START_OPTIMIZE
+These two optimizations apply to both pcre_exec() and
+pcre_dfa_exec(), and the information is also used by the JIT compiler.
+The optimizations can be disabled by setting the PCRE_NO_START_OPTIMIZE option
+when calling pcre_exec() or pcre_dfa_exec(), but if this is done,
+JIT execution is also disabled. You might want to do this if your pattern
+contains callouts or (*MARK) and you want to make use of these facilities in
+cases where matching fails. See the discussion of PCRE_NO_START_OPTIMIZE
below.
PCRE handles caseless matching, and determines whether characters are letters,
digits, or whatever, by reference to a set of tables, indexed by character
-value. When running in UTF-8 mode, this applies only to characters with codes
-less than 128. By default, higher-valued codes never match escapes such as \w
-or \d, but they can be tested with \p if PCRE is built with Unicode character
-property support. Alternatively, the PCRE_UCP option can be set at compile
-time; this causes \w and friends to use Unicode property support instead of
-built-in tables. The use of locales with Unicode is discouraged. If you are
-handling characters with codes greater than 128, you should either use UTF-8
-and Unicode, or use locales, but not try to mix the two.
+value. When running in UTF-8 mode, this applies only to characters
+with codes less than 128. By default, higher-valued codes never match escapes
+such as \w or \d, but they can be tested with \p if PCRE is built with
+Unicode character property support. Alternatively, the PCRE_UCP option can be
+set at compile time; this causes \w and friends to use Unicode property
+support instead of built-in tables. The use of locales with Unicode is
+discouraged. If you are handling characters with codes greater than 128, you
+should either use UTF-8 and Unicode, or use locales, but not try to mix the
+two.
PCRE contains an internal set of tables that are used when the final argument
@@ -939,16 +1093,16 @@
this facility could be used to match a pattern in a different locale from the
one in which it was compiled. Passing table pointers at run time is discussed
below in the section on matching a pattern.
-
int pcre_fullinfo(const pcre *code, const pcre_extra *extra,int what, void *where);
The pcre_fullinfo() function returns information about a compiled
-pattern. It replaces the obsolete pcre_info() function, which is
-nevertheless retained for backwards compability (and is documented below).
+pattern. It replaces the pcre_info() function, which was removed from the
+library at version 8.30, after more than 10 years of obsolescence.
The first argument for pcre_fullinfo() is a pointer to the compiled
@@ -958,20 +1112,24 @@
to receive the data. The yield of the function is zero for success, or one of
the following negative numbers:
- PCRE_ERROR_NULL the argument code was NULL
- the argument where was NULL
- PCRE_ERROR_BADMAGIC the "magic number" was not found
- PCRE_ERROR_BADOPTION the value of what was invalid
+ PCRE_ERROR_NULL the argument code was NULL
+ the argument where was NULL
+ PCRE_ERROR_BADMAGIC the "magic number" was not found
+ PCRE_ERROR_BADENDIANNESS the pattern was compiled with different
+ endianness
+ PCRE_ERROR_BADOPTION the value of what was invalid
The "magic number" is placed at the start of each compiled pattern as an simple
-check against passing an arbitrary memory pointer. Here is a typical call of
-pcre_fullinfo(), to obtain the length of the compiled pattern:
+check against passing an arbitrary memory pointer. The endianness error can
+occur if a compiled pattern is saved and reloaded on a different host. Here is
+a typical call of pcre_fullinfo(), to obtain the length of the compiled
+pattern:
int rc;
size_t length;
rc = pcre_fullinfo(
re, /* result of pcre_compile() */
- pe, /* result of pcre_study(), or NULL */
+ sd, /* result of pcre_study(), or NULL */
PCRE_INFO_SIZE, /* what is required */
&length); /* where to put the data */
@@ -999,14 +1157,19 @@
PCRE_INFO_FIRSTBYTE
-Return information about the first byte of any matched string, for a
-non-anchored pattern. The fourth argument should point to an int
-variable. (This option used to be called PCRE_INFO_FIRSTCHAR; the old name is
-still recognized for backwards compatibility.)
+Return information about the first data unit of any matched string, for a
+non-anchored pattern. (The name of this option refers to the 8-bit library,
+where data units are bytes.) The fourth argument should point to an int
+variable.
+
+
+If there is a fixed first value, for example, the letter "c" from a pattern
+such as (cat|cow|coyote), its value is returned. In the 8-bit library, the
+value is always less than 256; in the 16-bit library the value can be up to
+0xffff.
-If there is a fixed first byte, for example, from a pattern such as
-(cat|cow|coyote), its value is returned. Otherwise, if either
+If there is no fixed first value, and if either
(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch
@@ -1024,7 +1187,7 @@
PCRE_INFO_FIRSTTABLE
If the pattern was studied, and this resulted in the construction of a 256-bit
-table indicating a fixed set of bytes for the first byte in any matching
+table indicating a fixed set of values for the first data unit in any matching
string, a pointer to the table is returned. Otherwise NULL is returned. The
fourth argument should point to an unsigned char * variable.
@@ -1040,22 +1203,45 @@
0. The fourth argument should point to an int variable. (?J) and
(?-J) set and unset the local PCRE_DUPNAMES option, respectively.
+ PCRE_INFO_JIT
+
+Return 1 if the pattern was studied with one of the JIT options, and
+just-in-time compiling was successful. The fourth argument should point to an
+int variable. A return value of 0 means that JIT support is not available
+in this version of PCRE, or that the pattern was not studied with a JIT option,
+or that the JIT compiler could not handle this particular pattern. See the
+pcrejit
+documentation for details of what can and cannot be handled.
+
+ PCRE_INFO_JITSIZE
+
+If the pattern was successfully studied with a JIT option, return the size of
+the JIT compiled code, otherwise return zero. The fourth argument should point
+to a size_t variable.
+
PCRE_INFO_LASTLITERAL
-Return the value of the rightmost literal byte that must exist in any matched
-string, other than at its start, if such a byte has been recorded. The fourth
-argument should point to an int variable. If there is no such byte, -1 is
-returned. For anchored patterns, a last literal byte is recorded only if it
-follows something of variable length. For example, for the pattern
+Return the value of the rightmost literal data unit that must exist in any
+matched string, other than at its start, if such a value has been recorded. The
+fourth argument should point to an int variable. If there is no such
+value, -1 is returned. For anchored patterns, a last literal value is recorded
+only if it follows something of variable length. For example, for the pattern
/^a\d+z\d+/ the returned value is "z", but for /^a\dz\d/ the returned value
is -1.
+ PCRE_INFO_MAXLOOKBEHIND
+
+Return the number of characters (NB not bytes) in the longest lookbehind
+assertion in the pattern. Note that the simple assertions \b and \B require a
+one-character lookbehind. This information is useful when doing multi-segment
+matching using the partial matching facilities.
+
PCRE_INFO_MINLENGTH
If the pattern was studied and a minimum length for matching subject strings
was computed, its value is returned. Otherwise the returned value is -1. The
-value is a number of characters, not bytes (this may be relevant in UTF-8
-mode). The fourth argument should point to an int variable. A
+value is a number of characters, which in UTF-8 mode may be different from the
+number of bytes. The fourth argument should point to an int variable. A
non-negative value is a lower bound to the length of any matching string. There
may not be any strings of that length that do actually match, but every string
that does match is at least that long.
@@ -1079,9 +1265,11 @@
the number of entries, and PCRE_INFO_NAMEENTRYSIZE gives the size of each
entry; both of these return an int value. The entry size depends on the
length of the longest name. PCRE_INFO_NAMETABLE returns a pointer to the first
-entry of the table (a pointer to char). The first two bytes of each entry
-are the number of the capturing parenthesis, most significant byte first. The
-rest of the entry is the corresponding name, zero terminated.
+entry of the table. This is a pointer to char in the 8-bit library, where
+the first two bytes of each entry are the number of the capturing parenthesis,
+most significant byte first. In the 16-bit library, the pointer points to
+16-bit data units, the first of which contains the parenthesis number. The rest
+of the entry is the corresponding name, zero terminated.
The names are in alphabetical order. Duplicate names may appear if (?| is used
@@ -1097,8 +1285,8 @@
As a simple example of the name/number table, consider the following pattern
-(assume PCRE_EXTENDED is set, so white space - including newlines - is
-ignored):
+after compilation by the 8-bit library (assume PCRE_EXTENDED is set, so white
+space - including newlines - is ignored):
-Return the size of the compiled pattern, that is, the value that was passed as
-the argument to pcre_malloc() when PCRE was getting memory in which to
-place the compiled data. The fourth argument should point to a size_t
-variable.
+Return the size of the compiled pattern in bytes (for both libraries). The
+fourth argument should point to a size_t variable. This value does not
+include the size of the pcre structure that is returned by
+pcre_compile(). The value that is passed as the argument to
+pcre_malloc() when pcre_compile() is getting memory in which to
+place the compiled data is the value returned by this option plus the size of
+the pcre structure. Studying a compiled pattern, with or without JIT,
+does not alter the value returned by this option.
PCRE_INFO_STUDYSIZE
-Return the size of the data block pointed to by the study_data field in
-a pcre_extra block. That is, it is the value that was passed to
-pcre_malloc() when PCRE was getting memory into which to place the data
-created by pcre_study(). If pcre_extra is NULL, or there is no
+Return the size in bytes of the data block pointed to by the study_data
+field in a pcre_extra block. If pcre_extra is NULL, or there is no
study data, zero is returned. The fourth argument should point to a
-size_t variable.
-
- OBSOLETE INFO FUNCTION
-
-int pcre_info(const pcre *code, int *optptr, int
-*firstcharptr);
-
-
-The pcre_info() function is now obsolete because its interface is too
-restrictive to return all the available data about a compiled pattern. New
-programs should use pcre_fullinfo() instead. The yield of
-pcre_info() is the number of capturing subpatterns, or one of the
-following negative numbers:
-
- PCRE_ERROR_NULL the argument code was NULL
- PCRE_ERROR_BADMAGIC the "magic number" was not found
-
-If the optptr argument is not NULL, a copy of the options with which the
-pattern was compiled is placed in the integer it points to (see
-PCRE_INFO_OPTIONS above).
-
-
-If the pattern is not anchored and the firstcharptr argument is not NULL,
-it is used to pass back information about the first character of any matched
-string (see PCRE_INFO_FIRSTBYTE above).
+size_t variable. The study_data field is set by pcre_study()
+to record information that will speed up matching (see the section entitled
+"Studying a pattern"
+above). The format of the study_data block is private, but its length
+is made available via this option so that it can be saved and restored (see the
+pcreprecompile
+documentation for details).
int pcre_exec(const pcre *code, const pcre_extra *extra,const char *subject, int length, int startoffset,
@@ -1220,9 +1392,14 @@
The function pcre_exec() is called to match a subject string against a
compiled pattern, which is passed in the code argument. If the
pattern was studied, the result of the study should be passed in the
-extra argument. This function is the main matching facility of the
-library, and it operates in a Perl-like manner. For specialist use there is
-also an alternative matching function, which is described
+extra argument. You can call pcre_exec() with the same code
+and extra arguments as many times as you like, in order to match
+different subject strings with the same pattern.
+
+
+This function is the main matching facility of the library, and it operates in
+a Perl-like manner. For specialist use there is also an alternative matching
+function, which is described
below
in the section about the pcre_dfa_exec() function.
@@ -1263,26 +1440,33 @@
unsigned long int flags;
void *study_data;
+ void *executable_jit;
unsigned long int match_limit;
unsigned long int match_limit_recursion;
void *callout_data;
const unsigned char *tables;
unsigned char **mark;
-The flags field is a bitmap that specifies which of the other fields
-are set. The flag bits are:
+In the 16-bit version of this structure, the mark field has type
+"PCRE_UCHAR16 **".
+
+
+The flags field is used to specify which of the other fields are set. The
+flag bits are:
-Other flag bits should be set to zero. The study_data field is set in the
-pcre_extra block that is returned by pcre_study(), together with
-the appropriate flag bit. You should not set this yourself, but you may add to
-the block by setting the other fields and their corresponding flag bits.
+Other flag bits should be set to zero. The study_data field and sometimes
+the executable_jit field are set in the pcre_extra block that is
+returned by pcre_study(), together with the appropriate flag bits. You
+should not set these yourself, but you may add to the block by setting other
+fields and their corresponding flag bits.
The match_limit field provides a means of preventing PCRE from using up a
@@ -1291,12 +1475,19 @@
classic example is a pattern that uses nested unlimited repeats.
-Internally, PCRE uses a function called match() which it calls repeatedly
-(sometimes recursively). The limit set by match_limit is imposed on the
-number of times this function is called during a match, which has the effect of
-limiting the amount of backtracking that can take place. For patterns that are
-not anchored, the count restarts from zero for each position in the subject
-string.
+Internally, pcre_exec() uses a function called match(), which it
+calls repeatedly (sometimes recursively). The limit set by match_limit is
+imposed on the number of times this function is called during a match, which
+has the effect of limiting the amount of backtracking that can take place. For
+patterns that are not anchored, the count restarts from zero for each position
+in the subject string.
+
+
+When pcre_exec() is called with a pattern that was successfully studied
+with a JIT option, the way that the matching is executed is entirely different.
+However, there is still the possibility of runaway matching that goes on for a
+very long time, and so the match_limit value is also used in this case
+(but in a different way) to limit how long the matching can continue.
The default value for the limit can be set when PCRE is built; the default
@@ -1314,9 +1505,10 @@
This limit is of use only if it is set smaller than match_limit.
-Limiting the recursion depth limits the amount of stack that can be used, or,
-when PCRE has been compiled to use memory on the heap instead of the stack, the
-amount of heap memory that can be used.
+Limiting the recursion depth limits the amount of machine stack that can be
+used, or, when PCRE has been compiled to use memory on the heap instead of the
+stack, the amount of heap memory that can be used. This limit is not relevant,
+and is ignored, when matching is done using JIT compiled code.
The default value for match_limit_recursion can be set when PCRE is
@@ -1347,13 +1539,13 @@
If PCRE_EXTRA_MARK is set in the flags field, the mark field must
-be set to point to a char * variable. If the pattern contains any
+be set to point to a suitable variable. If the pattern contains any
backtracking control verbs such as (*MARK:NAME), and the execution ends up with
a name to pass back, a pointer to the name string (zero terminated) is placed
in the variable pointed to by the mark field. The names are within the
compiled pattern; if you wish to retain such a name you must copy it before
freeing the memory of a compiled pattern. If there is no name to pass back, the
-variable pointed to by the mark field set to NULL. For details of the
+variable pointed to by the mark field is set to NULL. For details of the
backtracking control verbs, see the section entitled
"Backtracking control"
in the
@@ -1367,8 +1559,16 @@
The unused bits of the options argument for pcre_exec() must be
zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx,
PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART,
-PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_SOFT, and
-PCRE_PARTIAL_HARD.
+PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and
+PCRE_PARTIAL_SOFT.
+
+
+If the pattern was successfully studied with one of the just-in-time (JIT)
+compile options, the only supported options for JIT execution are
+PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY,
+PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an
+unsupported option is used, JIT execution is disabled and the normal
+interpretive code in pcre_exec() is run.
PCRE_ANCHORED
@@ -1491,7 +1691,8 @@
"no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK)
are considered at every possible starting position in the subject string. If
PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching
-time.
+time. The use of PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set,
+matching is always done using interpretively.
Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation.
@@ -1525,17 +1726,21 @@
When PCRE_UTF8 is set at compile time, the validity of the subject as a UTF-8
string is automatically checked when pcre_exec() is subsequently called.
-The value of startoffset is also checked to ensure that it points to the
-start of a UTF-8 character. There is a discussion about the validity of UTF-8
-strings in the
-section on UTF-8 support
-in the main
-pcre
-page. If an invalid UTF-8 sequence of bytes is found, pcre_exec() returns
-the error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is
-a truncated UTF-8 character at the end of the subject, PCRE_ERROR_SHORTUTF8. If
-startoffset contains a value that does not point to the start of a UTF-8
-character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is
+The entire string is checked before any other processing takes place. The value
+of startoffset is also checked to ensure that it points to the start of a
+UTF-8 character. There is a discussion about the
+validity of UTF-8 strings
+in the
+pcreunicode
+page. If an invalid sequence of bytes is found, pcre_exec() returns the
+error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a
+truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In both
+cases, information about the precise nature of the error may also be returned
+(see the descriptions of these errors in the section entitled \fIError return
+values from\fP pcre_exec()
+below).
+If startoffset contains a value that does not point to the start of a
+UTF-8 character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is
returned.
@@ -1544,9 +1749,9 @@
calling pcre_exec(). You might want to do this for the second and
subsequent calls to pcre_exec() if you are making repeated calls to find
all the matches in a single subject string. However, you should be sure that
-the value of startoffset points to the start of a UTF-8 character (or the
-end of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an
-invalid UTF-8 string as a subject or an invalid value of startoffset is
+the value of startoffset points to the start of a character (or the end
+of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an
+invalid string as a subject or an invalid value of startoffset is
undefined. Your program may crash.
PCRE_PARTIAL_HARD
@@ -1581,7 +1786,7 @@
The subject string is passed to pcre_exec() as a pointer in
-subject, a length (in bytes) in length, and a starting byte offset
+subject, a length in bytes in length, and a starting byte offset
in startoffset. If this is negative or greater than the length of the
subject, pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting
offset is zero, the search for a match starts at the beginning of the subject,
@@ -1676,12 +1881,28 @@
If the vector is too small to hold all the captured substring offsets, it is
used as far as possible (up to two-thirds of its length), and the function
-returns a value of zero. If the substring offsets are not of interest,
-pcre_exec() may be called with ovector passed as NULL and
-ovecsize as zero. However, if the pattern contains back references and
-the ovector is not big enough to remember the related substrings, PCRE
-has to get additional memory for use during matching. Thus it is usually
-advisable to supply an ovector.
+returns a value of zero. If neither the actual string matched nor any captured
+substrings are of interest, pcre_exec() may be called with ovector
+passed as NULL and ovecsize as zero. However, if the pattern contains
+back references and the ovector is not big enough to remember the related
+substrings, PCRE has to get additional memory for use during matching. Thus it
+is usually advisable to supply an ovector of reasonable size.
+
+
+There are some cases where zero is returned (indicating vector overflow) when
+in fact the vector is exactly the right size for the final match. For example,
+consider the pattern
+
+ (a)(?:(b)c|bd)
+
+If a vector of 6 elements (allowing for only 1 captured substring) is given
+with subject string "abd", pcre_exec() will try to set the second
+captured string, thereby recording a vector overflow, before failing to match
+"c" and backing up to try the second alternative. The zero return, however,
+does correctly indicate that the maximum number of slots (namely 2) have been
+filled. In similar cases where there is temporary overflow, but the final
+number of used slots is actually less than the maximum, a non-zero value is
+returned.
The pcre_fullinfo() function can be used to find out how many capturing
@@ -1706,11 +1927,11 @@
(assuming the vector is large enough, of course) are set to -1.
-Note: Elements of ovector that do not correspond to capturing
-parentheses in the pattern are never changed. That is, if a pattern contains
-n capturing parentheses, no more than ovector[0] to
-ovector[2n+1] are set by pcre_exec(). The other elements retain
-whatever values they previously had.
+Note: Elements in the first two-thirds of ovector that do not
+correspond to capturing parentheses in the pattern are never changed. That is,
+if a pattern contains n capturing parentheses, no more than
+ovector[0] to ovector[2n+1] are set by pcre_exec(). The other
+elements (in the first two-thirds) retain whatever values they previously had.
Some convenience functions are provided for extracting the captured substrings
@@ -1784,14 +2005,21 @@
PCRE_ERROR_BADUTF8 (-10)
-A string that contains an invalid UTF-8 byte sequence was passed as a subject.
-However, if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8
-character at the end of the subject, PCRE_ERROR_SHORTUTF8 is used instead.
+A string that contains an invalid UTF-8 byte sequence was passed as a subject,
+and the PCRE_NO_UTF8_CHECK option was not set. If the size of the output vector
+(ovecsize) is at least 2, the byte offset to the start of the the invalid
+UTF-8 character is placed in the first element, and a reason code is placed in
+the second element. The reason codes are listed in the
+following section.
+For backward compatibility, if PCRE_PARTIAL_HARD is set and the problem is a
+truncated UTF-8 character at the end of the subject (reason codes 1 to 5),
+PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8.
PCRE_ERROR_BADUTF8_OFFSET (-11)
-The UTF-8 byte sequence that was passed as a subject was valid, but the value
-of startoffset did not point to the beginning of a UTF-8 character or the
+The UTF-8 byte sequence that was passed as a subject was checked and found to
+be valid (the PCRE_NO_UTF8_CHECK option was not set), but the value of
+startoffset did not point to the beginning of a UTF-8 character or the
end of the subject.
PCRE_ERROR_PARTIAL (-12)
@@ -1833,14 +2061,126 @@
PCRE_ERROR_SHORTUTF8 (-25)
-The subject string ended with an incomplete (truncated) UTF-8 character, and
-the PCRE_PARTIAL_HARD option was set. Without this option, PCRE_ERROR_BADUTF8
-is returned in this situation.
+This error is returned instead of PCRE_ERROR_BADUTF8 when the subject string
+ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD option is set.
+Information about the failure is returned as for PCRE_ERROR_BADUTF8. It is in
+fact sufficient to detect this case, but this special error code for
+PCRE_PARTIAL_HARD precedes the implementation of returned information; it is
+retained for backwards compatibility.
+
+ PCRE_ERROR_RECURSELOOP (-26)
+
+This error is returned when pcre_exec() detects a recursion loop within
+the pattern. Specifically, it means that either the whole pattern or a
+subpattern has been called recursively for the second time at the same position
+in the subject string. Some simple patterns that might do this are detected and
+faulted at compile time, but more complicated cases, in particular mutual
+recursions between two different subpatterns, cannot be detected until run
+time.
+
+ PCRE_ERROR_JIT_STACKLIMIT (-27)
+
+This error is returned when a pattern that was successfully studied using a
+JIT compile option is being matched, but the memory available for the
+just-in-time processing stack is not large enough. See the
+pcrejit
+documentation for more details.
+
+ PCRE_ERROR_BADMODE (-28)
+
+This error is given if a pattern that was compiled by the 8-bit library is
+passed to a 16-bit library function, or vice versa.
+
+ PCRE_ERROR_BADENDIANNESS (-29)
+
+This error is given if a pattern that was compiled and saved is reloaded on a
+host with different endianness. The utility function
+pcre_pattern_to_host_byte_order() can be used to convert such a pattern
+so that it runs on the new host.
+
+
+Error numbers -16 to -20, -22, and -30 are not used by pcre_exec().
+
+
+Reason codes for invalid UTF-8 strings
+
+
+This section applies only to the 8-bit library. The corresponding information
+for the 16-bit library is given in the
+pcre16
+page.
-Error numbers -16 to -20 and -22 are not used by pcre_exec().
+When pcre_exec() returns either PCRE_ERROR_BADUTF8 or
+PCRE_ERROR_SHORTUTF8, and the size of the output vector (ovecsize) is at
+least 2, the offset of the start of the invalid UTF-8 character is placed in
+the first output vector element (ovector[0]) and a reason code is placed
+in the second element (ovector[1]). The reason codes are given names in
+the pcre.h header file:
+
+The string ends with a truncated UTF-8 character; the code specifies how many
+bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 characters to be
+no longer than 4 bytes, the encoding scheme (originally defined by RFC 2279)
+allows for up to 6 bytes, and this is checked first; hence the possibility of
+4 or 5 missing bytes.
+
+The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of the
+character do not have the binary value 0b10 (that is, either the most
+significant bit is 0, or the next bit is 1).
+
+ PCRE_UTF8_ERR11
+ PCRE_UTF8_ERR12
+
+A character that is valid by the RFC 2279 rules is either 5 or 6 bytes long;
+these code points are excluded by RFC 3629.
+
+ PCRE_UTF8_ERR13
+
+A 4-byte character has a value greater than 0x10fff; these code points are
+excluded by RFC 3629.
+
+ PCRE_UTF8_ERR14
+
+A 3-byte character has a value in the range 0xd800 to 0xdfff; this range of
+code points are reserved by RFC 3629 for use with UTF-16, and so are excluded
+from UTF-8.
+
+A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes for a
+value that can be represented by fewer bytes, which is invalid. For example,
+the two bytes 0xc0, 0xae give the value 0x2e, whose correct coding uses just
+one byte.
+
+ PCRE_UTF8_ERR20
+
+The two most significant bits of the first byte of a character have the binary
+value 0b10 (that is, the most significant bit is 1 and the second is 0). Such a
+byte can only validly occur as the second or subsequent byte of a multi-byte
+character.
+
int pcre_copy_substring(const char *subject, int *ovector,int stringcount, int stringnumber, char *buffer,
@@ -1935,7 +2275,7 @@
pcre_free directly; it is for these cases that the functions are
provided.
int pcre_get_stringnumber(const pcre *code,const char *name);
@@ -1999,7 +2339,7 @@
numbers. For this reason, the use of different names for subpatterns of the
same number causes an error at compile time.
int pcre_get_stringtable_entries(const pcre *code,const char *name, char **first, char **last);
@@ -2032,11 +2372,12 @@
has run, they point to the first and last entries in the name-to-number table
for the given name. The function itself returns the length of each entry, or
PCRE_ERROR_NOSUBSTRING (-7) if there are none. The format of the table is
-described above in the section entitled Information about a pattern.
+described above in the section entitled Information about a pattern
+above.
Given all the relevant entries for the name, you can extract each of their
numbers, and hence the captured data, if any.
The traditional matching function uses a similar algorithm to Perl, which stops
when it finds the first match, starting at a given point in the subject. If you
@@ -2054,8 +2395,32 @@
substring. Then return 1, which forces pcre_exec() to backtrack and try
other alternatives. Ultimately, when it runs out of matches, pcre_exec()
will yield PCRE_ERROR_NOMATCH.
+
+Matching certain patterns using pcre_exec() can use a lot of process
+stack, which in certain environments can be rather limited in size. Some users
+find it helpful to have an estimate of the amount of stack that is used by
+pcre_exec(), to help them set recursion limits, as described in the
+pcrestack
+documentation. The estimate that is output by pcretest when called with
+the -m and -C options is obtained by calling pcre_exec with
+the values NULL, NULL, NULL, -999, and -999 for its first five arguments.
+
+
+Normally, if its first argument is NULL, pcre_exec() immediately returns
+the negative error code PCRE_ERROR_NULL, but with this special combination of
+arguments, it returns instead a negative number whose absolute value is the
+approximate stack frame size in bytes. (A negative number is used so that it is
+clear that no match has happened.) The value is approximate because in some
+cases, recursive calls to pcre_exec() occur when there are one or two
+additional variables on the stack.
+
+
+If PCRE has been compiled to use the heap instead of the stack for recursion,
+the value returned is the size of each block that is obtained from the heap.
int pcre_dfa_exec(const pcre *code, const pcre_extra *extra,const char *subject, int length, int startoffset,
@@ -2186,7 +2551,8 @@
The strings are returned in reverse order of length; that is, the longest
matching string is given first. If there were too many matches to fit into
ovector, the yield of the function is zero, and the vector is filled with
-the longest matches.
+the longest matches. Unlike pcre_exec(), pcre_dfa_exec() can use
+the entire ovector for returning matched strings.
Error returns from pcre_dfa_exec()
@@ -2213,8 +2579,9 @@
PCRE_ERROR_DFA_UMLIMIT (-18)
This return is given if pcre_dfa_exec() is called with an extra
-block that contains a setting of the match_limit field. This is not
-supported (it is meaningless).
+block that contains a setting of the match_limit or
+match_limit_recursion fields. This is not supported (these fields are
+meaningless for DFA matching).
PCRE_ERROR_DFA_WSSIZE (-19)
@@ -2227,14 +2594,21 @@
recursively, using private vectors for ovector and workspace. This
error is given if the output vector is not large enough. This should be
extremely rare, as a vector of size 1000 is used.
+
+ PCRE_ERROR_DFA_BADRESTART (-30)
+
+When pcre_dfa_exec() is called with the PCRE_DFA_RESTART option,
+some plausibility checks are made on the contents of the workspace, which
+should contain data about the previous partial match. If any of these checks
+fail, this error is given.
- SEE ALSO
+ SEE ALSO
@@ -61,45 +64,85 @@
--enable and --disable always come in pairs, so the complementary option always
exists as well, but as it specifies the default, it is not described.
-By default, the configure script will search for a C++ compiler and C++
-header files. If it finds them, it automatically builds the C++ wrapper library
-for PCRE. You can disable this by adding
+By default, a library called libpcre is built, containing functions that
+take string arguments contained in vectors of bytes, either as single-byte
+characters, or interpreted as UTF-8 strings. You can also build a separate
+library, called libpcre16, in which strings are contained in vectors of
+16-bit data units and interpreted either as single-unit characters or UTF-16
+strings, by adding
+
+ --enable-pcre16
+
+to the configure command. If you do not want the 8-bit library, add
+
+ --disable-pcre8
+
+as well. At least one of the two libraries must be built. Note that the C++ and
+POSIX wrappers are for the 8-bit library only, and that pcregrep is an
+8-bit program. None of these are built if you select only the 16-bit library.
+
+ BUILDING SHARED AND STATIC LIBRARIES
+
+The PCRE building process uses libtool to build both shared and static
+Unix libraries by default. You can suppress one of these by adding one of
+
+ --disable-shared
+ --disable-static
+
+to the configure command, as required.
+
+ C++ SUPPORT
+
+By default, if the 8-bit library is being built, the configure script
+will search for a C++ compiler and C++ header files. If it finds them, it
+automatically builds the C++ wrapper library (which supports only 8-bit
+strings). You can disable this by adding
-To build PCRE with support for UTF-8 Unicode character strings, add
+To build PCRE with support for UTF Unicode character strings, add
- --enable-utf8
+ --enable-utf
-to the configure command. Of itself, this does not make PCRE treat
-strings as UTF-8. As well as compiling PCRE with this option, you also have
-have to set the PCRE_UTF8 option when you call the pcre_compile()
-or pcre_compile2() functions.
+to the configure command. This setting applies to both libraries, adding
+support for UTF-8 to the 8-bit library and support for UTF-16 to the 16-bit
+library. There are no separate options for enabling UTF-8 and UTF-16
+independently because that would allow ridiculous settings such as requesting
+UTF-16 support while building only the 8-bit library. It is not possible to
+build one library with UTF support and the other without in the same
+configuration. (For backwards compatibility, --enable-utf8 is a synonym of
+--enable-utf.)
+
+
+Of itself, this setting does not make PCRE treat strings as UTF-8 or UTF-16. As
+well as compiling PCRE with this option, you also have have to set the
+PCRE_UTF8 or PCRE_UTF16 option when you call one of the pattern compiling
+functions.
-If you set --enable-utf8 when compiling in an EBCDIC environment, PCRE expects
-its input to be either ASCII or UTF-8 (depending on the runtime option). It is
+If you set --enable-utf when compiling in an EBCDIC environment, PCRE expects
+its input to be either ASCII or UTF-8 (depending on the run-time option). It is
not possible to support both EBCDIC and UTF-8 codes in the same version of the
-library. Consequently, --enable-utf8 and --enable-ebcdic are mutually
+library. Consequently, --enable-utf and --enable-ebcdic are mutually
exclusive.
-UTF-8 support allows PCRE to process character values greater than 255 in the
-strings that it handles. On its own, however, it does not provide any
+UTF support allows the libraries to process character codepoints up to 0x10ffff
+in the strings that they handle. On its own, however, it does not provide any
facilities for accessing the properties of such characters. If you want to be
able to use the pattern escapes \P, \p, and \X, which refer to Unicode
character properties, you must add
--enable-unicode-properties
-to the configure command. This implies UTF-8 support, even if you have
+to the configure command. This implies UTF support, even if you have
not explicitly requested it.
+Just-in-time compiler support is included in the build by specifying
+
+ --enable-jit
+
+This support is available only for certain hardware architectures. If this
+option is set for an unsupported architecture, a compile time error occurs.
+See the
+pcrejit
+documentation for a discussion of JIT usage. When JIT support is enabled,
+pcregrep automatically makes use of it, unless you add
+
By default, PCRE interprets the linefeed (LF) character as indicating the end
of a line. This is the normal newline character on Unix-like systems. You can
@@ -142,7 +202,7 @@
overridden when the library functions are called. At build time it is
conventional to use the standard for your operating system.
By default, the sequence \R in a pattern matches any Unicode newline sequence,
whatever has been selected as the line ending sequence. If you specify
@@ -153,19 +213,9 @@
selected when PCRE is built can be overridden when the library functions are
called.
-When PCRE is called through the POSIX interface (see the
+When the 8-bit library is called through the POSIX interface (see the
pcreposix
documentation), additional working storage is required for holding the pointers
to capturing substrings, because PCRE requires three integers per substring,
@@ -179,23 +229,24 @@
to the configure command.
Within a compiled pattern, offset values are used to point from one part to
another (for example, from an opening parenthesis to an alternation
metacharacter). By default, two-byte values are used for these offsets, leading
to a maximum size for a compiled pattern of around 64K. This is sufficient to
handle all but the most gigantic patterns. Nevertheless, some people do want to
-process truyl enormous patterns, so it is possible to compile PCRE to use
+process truly enormous patterns, so it is possible to compile PCRE to use
three-byte or four-byte offsets by adding a setting such as
--with-link-size=3
-to the configure command. The value given must be 2, 3, or 4. Using
-longer offsets slows down the operation of PCRE because it has to load
-additional bytes when handling them.
+to the configure command. The value given must be 2, 3, or 4. For the
+16-bit library, a value of 3 is rounded up to 4. Using longer offsets slows
+down the operation of PCRE because it has to load additional data when handling
+them.
- AVOIDING EXCESSIVE STACK USAGE
+ AVOIDING EXCESSIVE STACK USAGE
When matching with the pcre_exec() function, PCRE implements backtracking
by making recursive calls to an internal function called match(). In
@@ -226,7 +277,7 @@
slowly when built in this way. This option affects only the pcre_exec()
function; it is not relevant for pcre_dfa_exec().
Internally, PCRE has a function called match(), which it calls repeatedly
(sometimes recursively) when matching a pattern with the pcre_exec()
@@ -255,7 +306,7 @@
to the configure command. This value can also be overridden at run time.
PCRE uses fixed tables for processing characters whose code values are less
than 256. By default, PCRE is built with a set of tables that are distributed
@@ -266,13 +317,13 @@
to the configure command, the distributed tables are no longer used.
Instead, a program called dftables is compiled and run. This outputs the
-source for new set of tables, created in the default locale of your C runtime
+source for new set of tables, created in the default locale of your C run-time
system. (This method of replacing the tables does not work if you are cross
compiling, because dftables is run on the local host. If you need to
create alternative tables when cross compiling, you will have to do so "by
hand".)
PCRE assumes by default that it will run in an environment where the character
code is ASCII (or Unicode, which is a superset of ASCII). This is the case for
@@ -284,9 +335,9 @@
to the configure command. This setting implies
--enable-rebuild-chartables. You should only use it if you know that you are in
an EBCDIC environment (for example, an IBM mainframe operating system). The
---enable-ebcdic option is incompatible with --enable-utf8.
+--enable-ebcdic option is incompatible with --enable-utf.
By default, pcregrep reads all files as plain text. You can build it so
that it recognizes files whose names end in .gz or .bz2, and reads
@@ -299,7 +350,22 @@
relevant libraries are installed on your system. Configuration will fail if
they are not.
+pcregrep uses an internal buffer to hold a "window" on the file it is
+scanning, in order to be able to output "before" and "after" lines when it
+finds a match. The size of the buffer is controlled by a parameter whose
+default value is 20K. The buffer itself is three times this size, but because
+of the way it is used for holding "before" lines, the longest line that is
+guaranteed to be processable is the parameter size. You can change the default
+parameter value by adding, for example,
+
+ --with-pcregrep-bufsize=50K
+
+to the configure command. The caller of \fPpcregrep\fP can, however,
+override this value by specifying a run-time option.
+
+ PCRETEST OPTION FOR LIBREADLINE SUPPORT
Return to the PCRE index page.
diff -Nru pcre3-8.12/doc/html/pcrecallout.html pcre3-8.31/doc/html/pcrecallout.html
--- pcre3-8.12/doc/html/pcrecallout.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcrecallout.html 2012-07-06 09:55:27.000000000 +0000
@@ -25,11 +25,15 @@
int (*pcre_callout)(pcre_callout_block *);
+int (*pcre16_callout)(pcre16_callout_block *);
+
+
PCRE provides a feature called "callout", which is a means of temporarily
passing control to the caller of PCRE in the middle of pattern matching. The
caller of PCRE provides an external function by putting its entry point in the
-global variable pcre_callout. By default, this variable contains NULL,
-which disables all calling out.
+global variable pcre_callout (pcre16_callout for the 16-bit
+library). By default, this variable contains NULL, which disables all calling
+out.
Within a regular expression, (?C) indicates the points at which the external
@@ -39,10 +43,9 @@
(?C1)abc(?C2)def
-If the PCRE_AUTO_CALLOUT option bit is set when pcre_compile() or
-pcre_compile2() is called, PCRE automatically inserts callouts, all with
-number 255, before each item in the pattern. For example, if PCRE_AUTO_CALLOUT
-is used with the pattern
+If the PCRE_AUTO_CALLOUT option bit is set when a pattern is compiled, PCRE
+automatically inserts callouts, all with number 255, before each item in the
+pattern. For example, if PCRE_AUTO_CALLOUT is used with the pattern
A(\d{2}|--)
@@ -60,6 +63,11 @@
indicates how the pattern is matched. This is useful information when you are
trying to optimize the performance of a particular pattern.
+
+The use of callouts in a pattern makes it ineligible for optimization by the
+just-in-time compiler. Studying such a pattern with the PCRE_STUDY_JIT_COMPILE
+option always fails.
+
You should be aware that, because of optimizations in the way PCRE matches
@@ -81,33 +89,36 @@
You can disable these optimizations by passing the PCRE_NO_START_OPTIMIZE
-option to pcre_compile(), pcre_exec(), or pcre_dfa_exec(),
-or by starting the pattern with (*NO_START_OPT). This slows down the matching
-process, but does ensure that callouts such as the example above are obeyed.
+option to the matching function, or by starting the pattern with
+(*NO_START_OPT). This slows down the matching process, but does ensure that
+callouts such as the example above are obeyed.
During matching, when PCRE reaches a callout point, the external function
-defined by pcre_callout is called (if it is set). This applies to both
-the pcre_exec() and the pcre_dfa_exec() matching functions. The
-only argument to the callout function is a pointer to a pcre_callout
-block. This structure contains the following fields:
+defined by pcre_callout or pcre16_callout is called (if it is set).
+This applies to both normal and DFA matching. The only argument to the callout
+function is a pointer to a pcre_callout or pcre16_callout block.
+These structures contains the following fields:
- int version;
- int callout_number;
- int *offset_vector;
- const char *subject;
- int subject_length;
- int start_match;
- int current_position;
- int capture_top;
- int capture_last;
- void *callout_data;
- int pattern_position;
- int next_item_length;
+ int version;
+ int callout_number;
+ int *offset_vector;
+ const char *subject; (8-bit version)
+ PCRE_SPTR16 subject; (16-bit version)
+ int subject_length;
+ int start_match;
+ int current_position;
+ int capture_top;
+ int capture_last;
+ void *callout_data;
+ int pattern_position;
+ int next_item_length;
+ const unsigned char *mark; (8-bit version)
+ const PCRE_UCHAR16 *mark; (16-bit version)
The version field is an integer containing the version number of the
-block format. The initial version was 0; the current version is 1. The version
+block format. The initial version was 0; the current version is 2. The version
number will change again in future if additional fields are added, but the
intention is never to remove any of the existing fields.
@@ -118,15 +129,15 @@
The offset_vector field is a pointer to the vector of offsets that was
-passed by the caller to pcre_exec() or pcre_dfa_exec(). When
-pcre_exec() is used, the contents can be inspected in order to extract
+passed by the caller to the matching function. When pcre_exec() or
+pcre16_exec() is used, the contents can be inspected, in order to extract
substrings that have been matched so far, in the same way as for extracting
-substrings after a match has completed. For pcre_dfa_exec() this field is
-not useful.
+substrings after a match has completed. For the DFA matching functions, this
+field is not useful.
The subject and subject_length fields contain copies of the values
-that were passed to pcre_exec().
+that were passed to the matching function.
The start_match field normally contains the offset within the subject at
@@ -141,53 +152,59 @@
current match pointer.
-When the pcre_exec() function is used, the capture_top field
-contains one more than the number of the highest numbered captured substring so
-far. If no substrings have been captured, the value of capture_top is
-one. This is always the case when pcre_dfa_exec() is used, because it
-does not support captured substrings.
+When the pcre_exec() or pcre16_exec() is used, the
+capture_top field contains one more than the number of the highest
+numbered captured substring so far. If no substrings have been captured, the
+value of capture_top is one. This is always the case when the DFA
+functions are used, because they do not support captured substrings.
The capture_last field contains the number of the most recently captured
substring. If no substrings have been captured, its value is -1. This is always
-the case when pcre_dfa_exec() is used.
+the case for the DFA matching functions.
-The callout_data field contains a value that is passed to
-pcre_exec() or pcre_dfa_exec() specifically so that it can be
-passed back in callouts. It is passed in the pcre_callout field of the
-pcre_extra data structure. If no such data was passed, the value of
-callout_data in a pcre_callout block is NULL. There is a
-description of the pcre_extra structure in the
+The callout_data field contains a value that is passed to a matching
+function specifically so that it can be passed back in callouts. It is passed
+in the callout_data field of a pcre_extra or pcre16_extra
+data structure. If no such data was passed, the value of callout_data in
+a callout block is NULL. There is a description of the pcre_extra
+structure in the
pcreapi
documentation.
-The pattern_position field is present from version 1 of the
-pcre_callout structure. It contains the offset to the next item to be
-matched in the pattern string.
+The pattern_position field is present from version 1 of the callout
+structure. It contains the offset to the next item to be matched in the pattern
+string.
-The next_item_length field is present from version 1 of the
-pcre_callout structure. It contains the length of the next item to be
-matched in the pattern string. When the callout immediately precedes an
-alternation bar, a closing parenthesis, or the end of the pattern, the length
-is zero. When the callout precedes an opening parenthesis, the length is that
-of the entire subpattern.
+The next_item_length field is present from version 1 of the callout
+structure. It contains the length of the next item to be matched in the pattern
+string. When the callout immediately precedes an alternation bar, a closing
+parenthesis, or the end of the pattern, the length is zero. When the callout
+precedes an opening parenthesis, the length is that of the entire subpattern.
The pattern_position and next_item_length fields are intended to
help in distinguishing between different automatic callouts, which all have the
same callout number. However, they are set for all callouts.
+
+The mark field is present from version 2 of the callout structure. In
+callouts from pcre_exec() or pcre16_exec() it contains a pointer to
+the zero-terminated name of the most recently passed (*MARK), (*PRUNE), or
+(*THEN) item in the match, or NULL if no such items have been passed. Instances
+of (*PRUNE) or (*THEN) without a name do not obliterate a previous (*MARK). In
+callouts from the DFA matching functions this field always contains NULL.
+
The external callout function returns an integer to PCRE. If the value is zero,
matching proceeds as normal. If the value is greater than zero, matching fails
at the current point, but the testing of other matching possibilities goes
ahead, just as if a lookahead assertion had failed. If the value is less than
-zero, the match is abandoned, and pcre_exec() or pcre_dfa_exec()
-returns the negative value.
+zero, the match is abandoned, the matching function returns the negative value.
Negative values should normally be chosen from the set of PCRE_ERROR_xxx
@@ -206,9 +223,9 @@
Return to the PCRE index page.
diff -Nru pcre3-8.12/doc/html/pcrecompat.html pcre3-8.31/doc/html/pcrecompat.html
--- pcre3-8.12/doc/html/pcrecompat.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcrecompat.html 2012-07-06 09:55:27.000000000 +0000
@@ -21,18 +21,18 @@
versions 5.10 and above.
-1. PCRE has only a subset of Perl's UTF-8 and Unicode support. Details of what
-it does have are given in the
-section on UTF-8 support
-in the main
-pcre
+1. PCRE has only a subset of Perl's Unicode support. Details of what it does
+have are given in the
+pcreunicode
page.
-2. PCRE does not allow repeat quantifiers on lookahead assertions. Perl permits
-them, but they do not mean what you might think. For example, (?!a){3} does
-not assert that the next three characters are not "a". It just asserts that the
-next character is not "a" three times.
+2. PCRE allows repeat quantifiers only on parenthesized assertions, but they do
+not mean what you might think. For example, (?!a){3} does not assert that the
+next three characters are not "a". It just asserts that the next character is
+not "a" three times (in principle: PCRE optimizes this to run the assertion
+just once). Perl allows repeat quantifiers on other assertions such as \b, but
+these do not seem to have any use.
3. Capturing subpatterns that occur inside negative lookahead assertions are
@@ -49,9 +49,12 @@
5. The following Perl escape sequences are not supported: \l, \u, \L,
-\U, and \N. In fact these are implemented by Perl's general string-handling
-and are not part of its pattern matching engine. If any of these are
-encountered by PCRE, an error is generated.
+\U, and \N when followed by a character name or Unicode value. (\N on its
+own, matching a non-newline character, is supported.) In fact these are
+implemented by Perl's general string-handling and are not part of its pattern
+matching engine. If any of these are encountered by PCRE, an error is
+generated by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set,
+\U and \u are interpreted as JavaScript interprets them.
6. The Perl escape sequences \p, \P, and \X are supported only if PCRE is
@@ -64,7 +67,12 @@
implement the somewhat messy concept of surrogates."
-7. PCRE does support the \Q...\E escape for quoting substrings. Characters in
+7. PCRE implements a simpler version of \X than Perl, which changed to make
+\X match what Unicode calls an "extended grapheme cluster". This is more
+complicated than an extended Unicode sequence, which is what PCRE matches.
+
+
+8. PCRE does support the \Q...\E escape for quoting substrings. Characters in
between are treated as literals. This is slightly different from Perl in that $
and @ are also handled as literals inside the quotes. In Perl, they cause
variable interpolation (but of course PCRE does not have variables). Note the
@@ -79,7 +87,7 @@
The \Q...\E sequence is recognized both inside and outside character classes.
-8. Fairly obviously, PCRE does not support the (?{code}) and (??{code})
+9. Fairly obviously, PCRE does not support the (?{code}) and (??{code})
constructions. However, there is support for recursive patterns. This is not
available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE "callout"
feature allows an external function to be called during pattern matching. See
@@ -88,21 +96,35 @@
documentation for details.
-9. Subpatterns that are called recursively or as "subroutines" are always
-treated as atomic groups in PCRE. This is like Python, but unlike Perl. There
-is a discussion of an example that explains this in more detail in the
+10. Subpatterns that are called as subroutines (whether or not recursively) are
+always treated as atomic groups in PCRE. This is like Python, but unlike Perl.
+Captured values that are set outside a subroutine call can be reference from
+inside in PCRE, but not in Perl. There is a discussion that explains these
+differences in more detail in the
section on recursion differences from Perl
in the
pcrepattern
page.
-10. There are some differences that are concerned with the settings of captured
+11. If any of the backtracking control verbs are used in an assertion or in a
+subpattern that is called as a subroutine (whether or not recursively), their
+effect is confined to that subpattern; it does not extend to the surrounding
+pattern. This is not always the case in Perl. In particular, if (*THEN) is
+present in a group that is called as a subroutine, its action is limited to
+that group, even if the group does not contain any | characters. There is one
+exception to this: the name from a *(MARK), (*PRUNE), or (*THEN) that is
+encountered in a successful positive assertion is passed back when a
+match succeeds (compare capturing parentheses in assertions). Note that such
+subpatterns are processed as anchored at the point where they are tested.
+
+
+12. There are some differences that are concerned with the settings of captured
strings when part of a pattern is repeated. For example, matching "aba" against
the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE it is set to "b".
-11. PCRE's handling of duplicate subpattern numbers and duplicate subpattern
+13. PCRE's handling of duplicate subpattern numbers and duplicate subpattern
names is not as general as Perl's. This is a consequence of the fact the PCRE
works internally just with numbers, using an external table to translate
between numbers and names. In particular, a pattern such as (?|(?<a>A)|(?<b)B),
@@ -113,11 +135,13 @@
an error is given at compile time.
-12. Perl recognizes comments in some places that PCRE doesn't, for example,
-between the ( and ? at the start of a subpattern.
+14. Perl recognizes comments in some places that PCRE does not, for example,
+between the ( and ? at the start of a subpattern. If the /x modifier is set,
+Perl allows white space between ( and ? but PCRE never does, even if the
+PCRE_EXTENDED option is set.
-13. PCRE provides some extensions to the Perl regular expression facilities.
+15. PCRE provides some extensions to the Perl regular expression facilities.
Perl 5.10 includes new features that are not in earlier versions of Perl, some
of which (such as named parentheses) have been in PCRE for some time. This list
is with respect to Perl 5.10:
@@ -161,11 +185,12 @@
(j) Patterns compiled by PCRE can be saved and re-used at a later time, even on
-different hosts that have the other endianness.
+different hosts that have the other endianness. However, this does not apply to
+optimized data created by the just-in-time compiler.
-(k) The alternative matching function (pcre_dfa_exec()) matches in a
-different way and is not Perl-compatible.
+(k) The alternative matching functions (pcre_dfa_exec() and
+pcre16_dfa_exec()) match in a different way and are not Perl-compatible.
(l) PCRE recognizes some special sequences such as (*CR) at the start of
@@ -186,9 +211,9 @@
REVISION
Return to the PCRE index page.
diff -Nru pcre3-8.12/doc/html/pcrecpp.html pcre3-8.31/doc/html/pcrecpp.html
--- pcre3-8.12/doc/html/pcrecpp.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcrecpp.html 2012-07-06 09:55:28.000000000 +0000
@@ -35,7 +35,8 @@
The C++ wrapper for PCRE was provided by Google Inc. Some additional
functionality was added by Giuseppe Maxia. This brief man page was constructed
from the notes in the pcrecpp.h file, which should be consulted for
-further details.
+further details. Note that the C++ wrapper supports only the original 8-bit
+PCRE library. There is no 16-bit support at present.
-Last updated: 17 March 2009
+Last updated: 08 January 2012
Return to the PCRE index page.
diff -Nru pcre3-8.12/doc/html/pcredemo.html pcre3-8.31/doc/html/pcredemo.html
--- pcre3-8.12/doc/html/pcredemo.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcredemo.html 2012-07-06 09:55:28.000000000 +0000
@@ -265,7 +265,7 @@
* more than one byte. *
* *
* However, there is a complication concerned with newlines. When the *
-* newline convention is such that CRLF is a valid newline, we want must *
+* newline convention is such that CRLF is a valid newline, we must *
* advance by two characters rather than one. The newline convention can *
* be set in the regex by (*CR), etc.; if not, we must find the default. *
*************************************************************************/
diff -Nru pcre3-8.12/doc/html/pcregrep.html pcre3-8.31/doc/html/pcregrep.html
--- pcre3-8.12/doc/html/pcregrep.html 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/html/pcregrep.html 2012-07-06 09:55:27.000000000 +0000
@@ -16,16 +16,17 @@
@@ -74,11 +75,19 @@
boundary is controlled by the -N (--newline) option.
-Patterns are limited to 8K or BUFSIZ characters, whichever is the greater.
-BUFSIZ is defined in <stdio.h>. When there is more than one pattern
-(specified by the use of -e and/or -f), each pattern is applied to
-each line in the order in which they are defined, except that all the -e
-patterns are tried before the -f patterns.
+The amount of memory used for buffering files that are being scanned is
+controlled by a parameter that can be set by the --buffer-size option.
+The default value for this parameter is specified when pcregrep is built,
+with the default default being 20K. A block of memory three times this size is
+used (to allow for buffering "before" and "after" lines). An error occurs if a
+line overflows the buffer.
+
+
+Patterns are limited to 8K or BUFSIZ bytes, whichever is the greater. BUFSIZ is
+defined in <stdio.h>. When there is more than one pattern (specified by
+the use of -e and/or -f), each pattern is applied to each line in
+the order in which they are defined, except that all the -e patterns are
+tried before the -f patterns.
By default, as soon as one pattern matches (or fails to match when -v is
@@ -117,16 +126,24 @@
appropriate support is not present, files are treated as plain text. The
standard input is always so treated.
+By default, a file that contains a binary zero byte within the first 1024 bytes
+is identified as a binary file, and is processed specially. (GNU grep also
+identifies binary files in this manner.) See the --binary-files option
+for a means of changing the way binary files are handled.
+
The order in which some of the options appear can affect the output. For
example, both the -h and -l options affect the printing of file
names. Whichever comes later in the command line will be the one that takes
-effect.
+effect. Numerical values for options may be followed by K or M, to signify
+multiplication by 1024 or 1024*1024 respectively.
--
-This terminate the list of options. It is useful if the next item on the
+This terminates the list of options. It is useful if the next item on the
command line starts with a hyphen but is not an option. This allows for the
processing of patterns and filenames that start with hyphens.
@@ -140,6 +157,11 @@
guarantees to have up to 8K of following text available for context output.
+-a, --text
+Treat binary files as text. This is equivalent to
+--binary-files=text.
+
+
-Bnumber, --before-context=number
Output number lines of context before each matching line. If filenames
and/or line numbers are being output, a hyphen separator is used instead of a
@@ -149,6 +171,23 @@
guarantees to have up to 8K of preceding text available for context output.
+--binary-files=word
+Specify how binary files are to be processed. If the word is "binary" (the
+default), pattern matching is performed on binary files, but the only output is
+"Binary file <name> matches" when a match succeeds. If the word is "text",
+which is equivalent to the -a or --text option, binary files are
+processed in the same way as any other file. In this case, when a match
+succeeds, the output may be binary garbage, which can have nasty effects if
+sent to a terminal. If the word is "without-match", which is equivalent to the
+-I option, binary files are not processed at all; they are assumed not to
+be of interest.
+
+
+--buffer-size=number
+Set the parameter that controls how much memory is used for buffering files
+that are being scanned.
+
+
-Cnumber, --context=number
Output number lines of context both before and after each matching line.
This is equivalent to setting both -A and -B to the same value.
@@ -255,11 +294,22 @@
filename can be given as "-" to refer to the standard input. When -f is
used, patterns specified on the command line using -e may also be
present; they are tested before the file's patterns. However, no other pattern
-is taken from the command line; all arguments are treated as file names. There
-is an overall maximum of 100 patterns. Trailing white space is removed from
-each line, and blank lines are ignored. An empty file contains no patterns and
-therefore matches nothing. See also the comments about multiple patterns versus
-a single pattern with alternatives in the description of -e above.
+is taken from the command line; all arguments are treated as the names of paths
+to be searched. There is an overall maximum of 100 patterns. Trailing white
+space is removed from each line, and blank lines are ignored. An empty file
+contains no patterns and therefore matches nothing. See also the comments about
+multiple patterns versus a single pattern with alternatives in the description
+of -e above.
+
+
+--file-list=filename
+Read a list of files to be searched from the given file, one per line. Trailing
+white space is removed from each line, and blank lines are ignored. These files
+are searched before any others that may be listed on the command line. The
+filename can be given as "-" to refer to the standard input. If --file
+and --file-list are both specified as "-", patterns are read first. This
+is useful only when the standard input is a terminal, from which further lines
+(the list of files) can be read after an end-of-file indication.
--file-offsets
@@ -291,6 +341,11 @@
type support, and then exit.
+-I
+Treat binary files as never matching. This is equivalent to
+--binary-files=without-match.
+
+
-i, --ignore-case
Ignore upper/lower case distinctions during comparisons.
@@ -421,7 +476,7 @@
which recognizes any of the preceding three types, and an "any" convention, in
which any Unicode line ending sequence is assumed to end a line. The Unicode
sequences are the three just mentioned, plus VT (vertical tab, U+000B), FF
-(formfeed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and
+(form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and
PS (paragraph separator, U+2029).
@@ -442,6 +497,14 @@
--line-offsets is used.
+--no-jit
+If the PCRE library is built with support for just-in-time compiling (which
+speeds up matching), pcregrep automatically makes use of this, unless it
+was explicitly disabled at build time. This option can be used to disable the
+use of JIT at run time. It is provided for testing and working round problems.
+It should never be needed in normal use.
+
+
-o, --only-matching
Show only the part of the line that matched a pattern instead of the whole
line. In this mode, no context is shown. That is, the -A, -B, and
@@ -515,14 +578,14 @@
equivalent to having ^ and $ characters at the start and end of each
alternative branch in every pattern.
The environment variables LC_ALL and LC_CTYPE are examined, in that
order, for a locale. The first one that is set is used. This can be overridden
by the --locale option. If no locale is set, the PCRE library's default
(usually the "C" locale) is used.
The -N (--newline) option allows pcregrep to scan files with
different newline conventions from the default. However, the setting of this
@@ -531,16 +594,17 @@
printf() calls to indicate newlines, relying on the C I/O library to
convert this to an appropriate sequence if the output is sent to a file.
Many of the short and long forms of pcregrep's options are the same
-as in the GNU grep program (version 2.5.4). Any long option of the form
+as in the GNU grep program. Any long option of the form
--xxx-regexp (GNU terminology) is also available as --xxx-regex
-(PCRE terminology). However, the --file-offsets, --include-dir,
---line-offsets, --locale, --match-limit, -M,
---multiline, -N, --newline, --recursion-limit,
--u, and --utf-8 options are specific to pcregrep, as is the
-use of the --only-matching option with a capturing parentheses number.
+(PCRE terminology). However, the --file-list, --file-offsets,
+--include-dir, --line-offsets, --locale, --match-limit,
+-M, --multiline, -N, --newline,
+--recursion-limit, -u, and --utf-8 options are specific to
+pcregrep, as is the use of the --only-matching option with a
+capturing parentheses number.
Although most of the common options work the same way, a few are different in
@@ -549,7 +613,7 @@
-c and -l options are given, GNU grep lists only file names,
without counts, but pcregrep gives the counts.
There are four different ways in which an option with data can be specified.
If a short form option is used, the data may follow immediately, or (with one
@@ -581,7 +645,7 @@
options does have data, it must be given in the first form, using an equals
character. Otherwise pcregrep will assume that it has no data.
It is possible to supply a regular expression that takes a very long time to
fail to match certain lines. Such patterns normally involve nested indefinite
@@ -597,19 +661,19 @@
sets a limit on the amount of memory (usually stack) that is used (see the
discussion of these options above).
Exit status is 0 if any matches were found, 1 if no matches were found, and 2
-for syntax errors and non-existent or inacessible files (even if matches were
-found in other files) or too many matching errors. Using the -s option to
-suppress error messages about inaccessble files does not affect the return
-code.
+for syntax errors, overlong lines, non-existent or inaccessible files (even if
+matches were found in other files) or too many matching errors. Using the
+-s option to suppress error messages about inaccessible files does not
+affect the return code.
+This page is part of the PCRE HTML documentation. It was generated automatically
+from the original man page. If there is any nonsense in it, please consult the
+man page, in case the conversion went wrong.
+
+
+Just-in-time compiling is a heavyweight optimization that can greatly speed up
+pattern matching. However, it comes at the cost of extra processing before the
+match is performed. Therefore, it is of most benefit when the same pattern is
+going to be matched many times. This does not necessarily mean many calls of a
+matching function; if the pattern is not anchored, matching attempts may take
+place many times at various positions in the subject, even for a single call.
+Therefore, if the subject string is very long, it may still pay to use JIT for
+one-off matches.
+
+
+JIT support applies only to the traditional Perl-compatible matching function.
+It does not apply when the DFA matching function is being used. The code for
+this support was written by Zoltan Herczeg.
+
+JIT support is available for both the 8-bit and 16-bit PCRE libraries. To keep
+this documentation simple, only the 8-bit interface is described in what
+follows. If you are using the 16-bit library, substitute the 16-bit functions
+and 16-bit structures (for example, pcre16_jit_stack instead of
+pcre_jit_stack).
+
+JIT support is an optional feature of PCRE. The "configure" option --enable-jit
+(or equivalent CMake option) must be set when PCRE is built if you want to use
+JIT. The support is limited to the following hardware platforms:
+
+ ARM v5, v7, and Thumb2
+ Intel x86 32-bit and 64-bit
+ MIPS 32-bit
+ Power PC 32-bit and 64-bit
+
+If --enable-jit is set on an unsupported platform, compilation fails.
+
+
+A program that is linked with PCRE 8.20 or later can tell if JIT support is
+available by calling pcre_config() with the PCRE_CONFIG_JIT option. The
+result is 1 when JIT is available, and 0 otherwise. However, a simple program
+does not need to check this in order to use JIT. The API is implemented in a
+way that falls back to the interpretive code if JIT is not available.
+
+
+If your program may sometimes be linked with versions of PCRE that are older
+than 8.20, but you want to use JIT when it is available, you can test
+the values of PCRE_MAJOR and PCRE_MINOR, or the existence of a JIT macro such
+as PCRE_CONFIG_JIT, for compile-time control of your code.
+
+You have to do two things to make use of the JIT support in the simplest way:
+
+ (1) Call pcre_study() with the PCRE_STUDY_JIT_COMPILE option for
+ each compiled pattern, and pass the resulting pcre_extra block to
+ pcre_exec().
+
+ (2) Use pcre_free_study() to free the pcre_extra block when it is
+ no longer needed, instead of just freeing it yourself. This
+ ensures that any JIT data is also freed.
+
+For a program that may be linked with pre-8.20 versions of PCRE, you can insert
+
+PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for complete
+matches. If you want to run partial matches using the PCRE_PARTIAL_HARD or
+PCRE_PARTIAL_SOFT options of pcre_exec(), you should set one or both of
+the following options in addition to, or instead of, PCRE_STUDY_JIT_COMPILE
+when you call pcre_study():
+
+The JIT compiler generates different optimized code for each of the three
+modes (normal, soft partial, hard partial). When pcre_exec() is called,
+the appropriate code is run if it is available. Otherwise, the pattern is
+matched using interpretive code.
+
+
+In some circumstances you may need to call additional functions. These are
+described in the section entitled
+"Controlling the JIT stack"
+below.
+
+
+If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are ignored, and
+no JIT data is created. Otherwise, the compiled pattern is passed to the JIT
+compiler, which turns it into machine code that executes much faster than the
+normal interpretive code. When pcre_exec() is passed a pcre_extra
+block containing a pointer to JIT code of the appropriate mode (normal or
+hard/soft partial), it obeys that code instead of running the interpreter. The
+result is identical, but the compiled JIT code runs much faster.
+
+
+There are some pcre_exec() options that are not supported for JIT
+execution. There are also some pattern items that JIT cannot handle. Details
+are given below. In both cases, execution automatically falls back to the
+interpretive code. If you want to know whether JIT was actually used for a
+particular match, you should arrange for a JIT callback function to be set up
+as described in the section entitled
+"Controlling the JIT stack"
+below, even if you do not need to supply a non-default JIT stack. Such a
+callback function is called whenever JIT code is about to be obeyed. If the
+execution options are not right for JIT execution, the callback function is not
+obeyed.
+
+
+If the JIT compiler finds an unsupported item, no JIT data is generated. You
+can find out if JIT execution is available after studying a pattern by calling
+pcre_fullinfo() with the PCRE_INFO_JIT option. A result of 1 means that
+JIT compilation was successful. A result of 0 means that JIT support is not
+available, or the pattern was not studied with PCRE_STUDY_JIT_COMPILE etc., or
+the JIT compiler was not able to handle the pattern.
+
+
+Once a pattern has been studied, with or without JIT, it can be used as many
+times as you like for matching different subject strings.
+
+The only pcre_exec() options that are supported for JIT execution are
+PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NOTBOL, PCRE_NOTEOL,
+PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT.
+
+
+The unsupported pattern items are:
+
+ \C match a single byte; not supported in UTF-8 mode
+ (?Cn) callouts
+ (*PRUNE) )
+ (*SKIP) ) backtracking control verbs
+ (*THEN) )
+
+When a pattern is matched using JIT execution, the return values are the same
+as those given by the interpretive pcre_exec() code, with the addition of
+one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means that the memory used
+for the JIT stack was insufficient. See
+"Controlling the JIT stack"
+below for a discussion of JIT stack usage. For compatibility with the
+interpretive pcre_exec() code, no more than two-thirds of the
+ovector argument is used for passing back captured substrings.
+
+
+The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if searching a
+very large pattern tree goes on for too long, as it is in the same circumstance
+when JIT is not used, but the details of exactly what is counted are not the
+same. The PCRE_ERROR_RECURSIONLIMIT error code is never returned by JIT
+execution.
+
+The code that is generated by the JIT compiler is architecture-specific, and is
+also position dependent. For those reasons it cannot be saved (in a file or
+database) and restored later like the bytecode and other data of a compiled
+pattern. Saving and restoring compiled patterns is not something many people
+do. More detail about this facility is given in the
+pcreprecompile
+documentation. It should be possible to run pcre_study() on a saved and
+restored pattern, and thereby recreate the JIT data, but because JIT
+compilation uses significant resources, it is probably not worth doing this;
+you might as well recompile the original pattern.
+
+When the compiled JIT code runs, it needs a block of memory to use as a stack.
+By default, it uses 32K on the machine stack. However, some large or
+complicated patterns need more than this. The error PCRE_ERROR_JIT_STACKLIMIT
+is given when there is not enough stack. Three functions are provided for
+managing blocks of memory for use as JIT stacks. There is further discussion
+about the use of JIT stacks in the section entitled
+"JIT stack FAQ"
+below.
+
+
+The pcre_jit_stack_alloc() function creates a JIT stack. Its arguments
+are a starting size and a maximum size, and it returns a pointer to an opaque
+structure of type pcre_jit_stack, or NULL if there is an error. The
+pcre_jit_stack_free() function can be used to free a stack that is no
+longer needed. (For the technically minded: the address space is allocated by
+mmap or VirtualAlloc.)
+
+
+JIT uses far less memory for recursion than the interpretive code,
+and a maximum stack size of 512K to 1M should be more than enough for any
+pattern.
+
+
+The pcre_assign_jit_stack() function specifies which stack JIT code
+should use. Its arguments are as follows:
+
+The extra argument must be the result of studying a pattern with
+PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the other
+two options:
+
+ (1) If callback is NULL and data is NULL, an internal 32K block
+ on the machine stack is used.
+
+ (2) If callback is NULL and data is not NULL, data must be
+ a valid JIT stack, the result of calling pcre_jit_stack_alloc().
+
+ (3) If callback is not NULL, it must point to a function that is
+ called with data as an argument at the start of matching, in
+ order to set up a JIT stack. If the return from the callback
+ function is NULL, the internal 32K stack is used; otherwise the
+ return value must be a valid JIT stack, the result of calling
+ pcre_jit_stack_alloc().
+
+A callback function is obeyed whenever JIT code is about to be run; it is not
+obeyed when pcre_exec() is called with options that are incompatible for
+JIT execution. A callback function can therefore be used to determine whether a
+match operation was executed by JIT or by the interpreter.
+
+
+You may safely use the same JIT stack for more than one pattern (either by
+assigning directly or by callback), as long as the patterns are all matched
+sequentially in the same thread. In a multithread application, if you do not
+specify a JIT stack, or if you assign or pass back NULL from a callback, that
+is thread-safe, because each thread has its own machine stack. However, if you
+assign or pass back a non-NULL JIT stack, this must be a different stack for
+each thread so that the application is thread-safe.
+
+
+Strictly speaking, even more is allowed. You can assign the same non-NULL stack
+to any number of patterns as long as they are not used for matching by multiple
+threads at the same time. For example, you can assign the same stack to all
+compiled patterns, and use a global mutex in the callback to wait until the
+stack is available for use. However, this is an inefficient solution, and not
+recommended.
+
+
+This is a suggestion for how a multithreaded program that needs to set up
+non-default JIT stacks might operate:
+
+ During thread initalization
+ thread_local_var = pcre_jit_stack_alloc(...)
+
+ During thread exit
+ pcre_jit_stack_free(thread_local_var)
+
+ Use a one-line callback function
+ return thread_local_var
+
+All the functions described in this section do nothing if JIT is not available,
+and pcre_assign_jit_stack() does nothing unless the extra argument
+is non-NULL and points to a pcre_extra block that is the result of a
+successful study with PCRE_STUDY_JIT_COMPILE etc.
+
+ JIT STACK FAQ
+
+(1) Why do we need JIT stacks?
+
+
+PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack where
+the local data of the current node is pushed before checking its child nodes.
+Allocating real machine stack on some platforms is difficult. For example, the
+stack chain needs to be updated every time if we extend the stack on PowerPC.
+Although it is possible, its updating time overhead decreases performance. So
+we do the recursion in memory.
+
+
+(2) Why don't we simply allocate blocks of memory with malloc()?
+
+
+Modern operating systems have a nice feature: they can reserve an address space
+instead of allocating memory. We can safely allocate memory pages inside this
+address space, so the stack could grow without moving memory data (this is
+important because of pointers). Thus we can allocate 1M address space, and use
+only a single memory page (usually 4K) if that is enough. However, we can still
+grow up to 1M anytime if needed.
+
+
+(3) Who "owns" a JIT stack?
+
+
+The owner of the stack is the user program, not the JIT studied pattern or
+anything else. The user program must ensure that if a stack is used by
+pcre_exec(), (that is, it is assigned to the pattern currently running),
+that stack must not be used by any other threads (to avoid overwriting the same
+memory area). The best practice for multithreaded programs is to allocate a
+stack for each thread, and return this stack through the JIT callback function.
+
+
+(4) When should a JIT stack be freed?
+
+
+You can free a JIT stack at any time, as long as it will not be used by
+pcre_exec() again. When you assign the stack to a pattern, only a pointer
+is set. There is no reference counting or any other magic. You can free the
+patterns and stacks in any order, anytime. Just do not call
+pcre_exec() with a pattern pointing to an already freed stack, as that
+will cause SEGFAULT. (Also, do not free a stack currently used by
+pcre_exec() in another thread). You can also replace the stack for a
+pattern at any time. You can even free the previous stack before assigning a
+replacement.
+
+
+(5) Should I allocate/free a stack every time before/after calling
+pcre_exec()?
+
+
+No, because this is too costly in terms of resources. However, you could
+implement some clever idea which release the stack if it is not used in let's
+say two minutes. The JIT callback can help to achive this without keeping a
+list of the currently JIT studied patterns.
+
+
+(6) OK, the stack is for long term memory allocation. But what happens if a
+pattern causes stack overflow with a stack of 1M? Is that 1M kept until the
+stack is freed?
+
+
+Especially on embedded sytems, it might be a good idea to release memory
+sometimes without freeing the stack. There is no API for this at the moment.
+Probably a function call which returns with the currently allocated memory for
+any stack and another which allows releasing memory (shrinking the stack) would
+be a good idea if someone needs this.
+
+
+(7) This is too much of a headache. Isn't there any better solution for JIT
+stack handling?
+
+
+No, thanks to Windows. If POSIX threads were used everywhere, we could throw
+out this complicated API.
+
+This page is part of the PCRE HTML documentation. It was generated automatically
+from the original man page. If there is any nonsense in it, please consult the
+man page, in case the conversion went wrong.
+
+
+SIZE AND OTHER LIMITATIONS
+
+
+There are some size limitations in PCRE but it is hoped that they will never in
+practice be relevant.
+
+
+The maximum length of a compiled pattern is approximately 64K data units (bytes
+for the 8-bit library, 16-bit units for the 16-bit library) if PCRE is compiled
+with the default internal linkage size of 2 bytes. If you want to process
+regular expressions that are truly enormous, you can compile PCRE with an
+internal linkage size of 3 or 4 (when building the 16-bit library, 3 is rounded
+up to 4). See the README file in the source distribution and the
+pcrebuild
+documentation for details. In these cases the limit is substantially larger.
+However, the speed of execution is slower.
+
+
+All values in repeating quantifiers must be less than 65536.
+
+
+There is no limit to the number of parenthesized subpatterns, but there can be
+no more than 65535 capturing subpatterns.
+
+
+There is a limit to the number of forward references to subsequent subpatterns
+of around 200,000. Repeated forward references with fixed upper limits, for
+example, (?2){0,100} when subpattern number 2 is to the right, are included in
+the count. There is no limit to the number of backward references.
+
+
+The maximum length of name for a named subpattern is 32 characters, and the
+maximum number of named subpatterns is 10000.
+
+
+The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or (*THEN) verb
+is 255 for the 8-bit library and 65535 for the 16-bit library.
+
+
+The maximum length of a subject string is the largest positive number that an
+integer variable can hold. However, when using the traditional matching
+function, PCRE uses recursion to handle subpatterns and indefinite repetition.
+This means that the available stack space may limit the size of a subject
+string that can be processed by certain patterns. For a discussion of stack
+issues, see the
+pcrestack
+documentation.
+
This document describes the two different algorithms that are available in PCRE
for matching a compiled regular expression against a given subject string. The
-"standard" algorithm is the one provided by the pcre_exec() function.
-This works in the same was as Perl's matching function, and provides a
-Perl-compatible matching operation.
+"standard" algorithm is the one provided by the pcre_exec() and
+pcre16_exec() functions. These work in the same was as Perl's matching
+function, and provide a Perl-compatible matching operation. The just-in-time
+(JIT) optimization that is described in the
+pcrejit
+documentation is compatible with these functions.
-An alternative algorithm is provided by the pcre_dfa_exec() function;
-this operates in a different way, and is not Perl-compatible. It has advantages
-and disadvantages compared with the standard algorithm, and these are described
-below.
+An alternative algorithm is provided by the pcre_dfa_exec() and
+pcre16_dfa_exec() functions; they operate in a different way, and are not
+Perl-compatible. This alternative has advantages and disadvantages compared
+with the standard algorithm, and these are described below.
When there is only one possible way in which a given subject string can match a
@@ -163,10 +166,10 @@
always 1, and the value of the capture_last field is always -1.
-7. The \C escape sequence, which (in the standard algorithm) matches a single
-byte, even in UTF-8 mode, is not supported because the alternative algorithm
-moves through the subject string one character at a time, for all active paths
-through the tree.
+7. The \C escape sequence, which (in the standard algorithm) always matches a
+single data unit, even in UTF-8 or UTF-16 modes, is not supported in these
+modes, because the alternative algorithm moves through the subject string one
+character (not data unit) at a time, for all active paths through the tree.
8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) are not
@@ -184,11 +187,11 @@
2. Because the alternative algorithm scans the subject string just once, and
-never needs to backtrack, it is possible to pass very long subject strings to
-the matching function in several pieces, checking for partial matching each
-time. Although it is possible to do multi-segment matching using the standard
-algorithm (pcre_exec()), by retaining partially matched substrings, it is
-more complicated. The
+never needs to backtrack (except for lookbehinds), it is possible to pass very
+long subject strings to the matching function in several pieces, checking for
+partial matching each time. Although it is possible to do multi-segment
+matching using the standard algorithm by retaining partially matched
+substrings, it is more complicated. The
pcrepartial
documentation gives details of partial matching and discusses multi-segment
matching.
@@ -220,9 +223,9 @@
-In normal use of PCRE, if the subject string that is passed to
-pcre_exec() or pcre_dfa_exec() matches as far as it goes, but is
-too short to match the entire pattern, PCRE_ERROR_NOMATCH is returned. There
-are circumstances where it might be helpful to distinguish this case from other
-cases in which there is no match.
+In normal use of PCRE, if the subject string that is passed to a matching
+function matches as far as it goes, but is too short to match the entire
+pattern, PCRE_ERROR_NOMATCH is returned. There are circumstances where it might
+be helpful to distinguish this case from other cases in which there is no
+match.
Consider, for example, an application where a human is required to type in data
@@ -50,40 +50,51 @@
PCRE supports partial matching by means of the PCRE_PARTIAL_SOFT and
-PCRE_PARTIAL_HARD options, which can be set when calling pcre_exec() or
-pcre_dfa_exec(). For backwards compatibility, PCRE_PARTIAL is a synonym
-for PCRE_PARTIAL_SOFT. The essential difference between the two options is
-whether or not a partial match is preferred to an alternative complete match,
-though the details differ between the two matching functions. If both options
+PCRE_PARTIAL_HARD options, which can be set when calling any of the matching
+functions. For backwards compatibility, PCRE_PARTIAL is a synonym for
+PCRE_PARTIAL_SOFT. The essential difference between the two options is whether
+or not a partial match is preferred to an alternative complete match, though
+the details differ between the two types of matching function. If both options
are set, PCRE_PARTIAL_HARD takes precedence.
-Setting a partial matching option disables two of PCRE's optimizations. PCRE
-remembers the last literal byte in a pattern, and abandons matching immediately
-if such a byte is not present in the subject string. This optimization cannot
-be used for a subject string that might match only partially. If the pattern
-was studied, PCRE knows the minimum length of a matching string, and does not
-bother to run the matching function on shorter strings. This optimization is
-also disabled for partial matching.
-
-A partial match occurs during a call to pcre_exec() when the end of the
-subject string is reached successfully, but matching cannot continue because
-more characters are needed. However, at least one character in the subject must
-have been inspected. This character need not form part of the final matched
-string; lookbehind assertions and the \K escape sequence provide ways of
-inspecting characters before the start of a matched substring. The requirement
-for inspecting at least one character exists because an empty string can always
-be matched; without such a restriction there would always be a partial match of
-an empty string at the end of the subject.
-
-
-If there are at least two slots in the offsets vector when pcre_exec()
-returns with a partial match, the first slot is set to the offset of the
-earliest character that was inspected when the partial match was found. For
-convenience, the second offset points to the end of the subject so that a
-substring can easily be identified.
+If you want to use partial matching with just-in-time optimized code, you must
+call pcre_study() or pcre16_study() with one or both of these
+options:
+
+PCRE_STUDY_JIT_COMPILE should also be set if you are going to run non-partial
+matches on the same pattern. If the appropriate JIT study mode has not been set
+for a match, the interpretive matching code is used.
+
+
+Setting a partial matching option disables two of PCRE's standard
+optimizations. PCRE remembers the last literal data unit in a pattern, and
+abandons matching immediately if it is not present in the subject string. This
+optimization cannot be used for a subject string that might match only
+partially. If the pattern was studied, PCRE knows the minimum length of a
+matching string, and does not bother to run the matching function on shorter
+strings. This optimization is also disabled for partial matching.
+
+A partial match occurs during a call to pcre_exec() or
+pcre16_exec() when the end of the subject string is reached successfully,
+but matching cannot continue because more characters are needed. However, at
+least one character in the subject must have been inspected. This character
+need not form part of the final matched string; lookbehind assertions and the
+\K escape sequence provide ways of inspecting characters before the start of a
+matched substring. The requirement for inspecting at least one character exists
+because an empty string can always be matched; without such a restriction there
+would always be a partial match of an empty string at the end of the subject.
+
+
+If there are at least two slots in the offsets vector when a partial match is
+returned, the first slot is set to the offset of the earliest character that
+was inspected. For convenience, the second offset points to the end of the
+subject so that a substring can easily be identified.
For the majority of patterns, the first offset identifies the start of the
@@ -103,13 +114,14 @@
partial matching options are set.
-PCRE_PARTIAL_SOFT with pcre_exec()
+PCRE_PARTIAL_SOFT WITH pcre_exec() OR pcre16_exec()
-If PCRE_PARTIAL_SOFT is set when pcre_exec() identifies a partial match,
-the partial match is remembered, but matching continues as normal, and other
-alternatives in the pattern are tried. If no complete match can be found,
-pcre_exec() returns PCRE_ERROR_PARTIAL instead of PCRE_ERROR_NOMATCH.
+If PCRE_PARTIAL_SOFT is set when pcre_exec() or pcre16_exec()
+identifies a partial match, the partial match is remembered, but matching
+continues as normal, and other alternatives in the pattern are tried. If no
+complete match can be found, PCRE_ERROR_PARTIAL is returned instead of
+PCRE_ERROR_NOMATCH.
This option is "soft" because it prefers a complete match over a partial match.
@@ -132,22 +144,25 @@
matches the second alternative.)
-PCRE_PARTIAL_HARD with pcre_exec()
+PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre16_exec()
-If PCRE_PARTIAL_HARD is set for pcre_exec(), it returns
-PCRE_ERROR_PARTIAL as soon as a partial match is found, without continuing to
-search for possible complete matches. This option is "hard" because it prefers
-an earlier partial match over a later complete match. For this reason, the
-assumption is made that the end of the supplied subject string may not be the
-true end of the available data, and so, if \z, \Z, \b, \B, or $ are
-encountered at the end of the subject, the result is PCRE_ERROR_PARTIAL.
-
-
-Setting PCRE_PARTIAL_HARD also affects the way pcre_exec() checks UTF-8
-subject strings for validity. Normally, an invalid UTF-8 sequence causes the
-error PCRE_ERROR_BADUTF8. However, in the special case of a truncated UTF-8
-character at the end of the subject, PCRE_ERROR_SHORTUTF8 is returned when
+If PCRE_PARTIAL_HARD is set for pcre_exec() or pcre16_exec(),
+PCRE_ERROR_PARTIAL is returned as soon as a partial match is found, without
+continuing to search for possible complete matches. This option is "hard"
+because it prefers an earlier partial match over a later complete match. For
+this reason, the assumption is made that the end of the supplied subject string
+may not be the true end of the available data, and so, if \z, \Z, \b, \B,
+or $ are encountered at the end of the subject, the result is
+PCRE_ERROR_PARTIAL, provided that at least one character in the subject has
+been inspected.
+
+
+Setting PCRE_PARTIAL_HARD also affects the way UTF-8 and UTF-16
+subject strings are checked for validity. Normally, an invalid sequence
+causes the error PCRE_ERROR_BADUTF8 or PCRE_ERROR_BADUTF16. However, in the
+special case of a truncated character at the end of the subject,
+PCRE_ERROR_SHORTUTF8 or PCRE_ERROR_SHORTUTF16 is returned when
PCRE_PARTIAL_HARD is set.
@@ -167,23 +182,23 @@
/dog(sbody)??/
-In this case the result is always a complete match because pcre_exec()
-finds that first, and it never continues after finding a match. It might be
-easier to follow this explanation by thinking of the two patterns like this:
+In this case the result is always a complete match because that is found first,
+and matching never continues after finding a complete match. It might be easier
+to follow this explanation by thinking of the two patterns like this:
/dog(sbody)?/ is the same as /dogsbody|dog/
/dog(sbody)??/ is the same as /dog|dogsbody/
-The pcre_dfa_exec() function moves along the subject string character by
-character, without backtracking, searching for all possible matches
-simultaneously. If the end of the subject is reached before the end of the
-pattern, there is the possibility of a partial match, again provided that at
-least one character has been inspected.
+The DFA functions move along the subject string character by character, without
+backtracking, searching for all possible matches simultaneously. If the end of
+the subject is reached before the end of the pattern, there is the possibility
+of a partial match, again provided that at least one character has been
+inspected.
When PCRE_PARTIAL_SOFT is set, PCRE_ERROR_PARTIAL is returned only if there
@@ -194,16 +209,16 @@
at least two slots in the offsets vector.
-Because pcre_dfa_exec() always searches for all possible matches, and
-there is no difference between greedy and ungreedy repetition, its behaviour is
-different from pcre_exec when PCRE_PARTIAL_HARD is set. Consider the
-string "dog" matched against the ungreedy pattern shown above:
+Because the DFA functions always search for all possible matches, and there is
+no difference between greedy and ungreedy repetition, their behaviour is
+different from the standard functions when PCRE_PARTIAL_HARD is set. Consider
+the string "dog" matched against the ungreedy pattern shown above:
/dog(sbody)??/
-Whereas pcre_exec() stops as soon as it finds the complete match for
-"dog", pcre_dfa_exec() also finds the partial match for "dogsbody", and
-so returns that when PCRE_PARTIAL_HARD is set.
+Whereas the standard functions stop as soon as they find the complete match for
+"dog", the DFA functions also find the partial match for "dogsbody", and so
+return that when PCRE_PARTIAL_HARD is set.
PARTIAL MATCHING AND WORD BOUNDARIES
@@ -215,15 +230,11 @@
This matches "cat", provided there is a word boundary at either end. If the
subject string is "the cat", the comparison of the final "t" with a following
-character cannot take place, so a partial match is found. However,
-pcre_exec() carries on with normal matching, which matches \b at the end
-of the subject when the last character is a letter, thus finding a complete
-match. The result, therefore, is not PCRE_ERROR_PARTIAL. The same thing
-happens with pcre_dfa_exec(), because it also finds the complete match.
-
-
-Using PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, because
-then the partial match takes precedence.
+character cannot take place, so a partial match is found. However, normal
+matching carries on, and \b matches at the end of the subject when the last
+character is a letter, so a complete match is found. The result, therefore, is
+not PCRE_ERROR_PARTIAL. Using PCRE_PARTIAL_HARD in this case does yield
+PCRE_ERROR_PARTIAL, because then the partial match takes precedence.
@@ -231,7 +242,7 @@
optimizations were implemented in the pcre_exec() function, the
PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be used with
all patterns. From release 8.00 onwards, the restrictions no longer apply, and
-partial matching with pcre_exec() can be requested for any pattern.
+partial matching with can be requested for any pattern.
Items that were formerly restricted were repeated single characters and
@@ -263,22 +274,21 @@
The first data string is matched completely, so pcretest shows the
matched substrings. The remaining four strings do not match the complete
pattern, but the first two are partial matches. Similar output is obtained
-when pcre_dfa_exec() is used.
+if DFA matching is used.
If the escape sequence \P is present more than once in a pcretest data
line, the PCRE_PARTIAL_HARD option is set for the match.
-When a partial match has been found using pcre_dfa_exec(), it is possible
-to continue the match by providing additional subject data and calling
-pcre_dfa_exec() again with the same compiled regular expression, this
-time setting the PCRE_DFA_RESTART option. You must pass the same working
-space as before, because this is where details of the previous partial match
-are stored. Here is an example using pcretest, using the \R escape
-sequence to set the PCRE_DFA_RESTART option (\D specifies the use of
-pcre_dfa_exec()):
+When a partial match has been found using a DFA matching function, it is
+possible to continue the match by providing additional subject data and calling
+the function again with the same compiled regular expression, this time setting
+the PCRE_DFA_RESTART option. You must pass the same working space as before,
+because this is where details of the previous partial match are stored. Here is
+an example using pcretest, using the \R escape sequence to set the
+PCRE_DFA_RESTART option (\D specifies the use of the DFA matching function):
You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with
PCRE_DFA_RESTART to continue partial matching over multiple segments. This
-facility can be used to pass very long subject strings to
-pcre_dfa_exec().
+facility can be used to pass very long subject strings to the DFA matching
+functions.
-From release 8.00, pcre_exec() can also be used to do multi-segment
-matching. Unlike pcre_dfa_exec(), it is not possible to restart the
-previous match with a new segment of data. Instead, new data must be added to
-the previous subject string, and the entire match re-run, starting from the
-point where the partial match occurred. Earlier data can be discarded. It is
-best to use PCRE_PARTIAL_HARD in this situation, because it does not treat the
-end of a segment as the end of the subject when matching \z, \Z, \b, \B,
-and $. Consider an unanchored pattern that matches dates:
+From release 8.00, the standard matching functions can also be used to do
+multi-segment matching. Unlike the DFA functions, it is not possible to
+restart the previous match with a new segment of data. Instead, new data must
+be added to the previous subject string, and the entire match re-run, starting
+from the point where the partial match occurred. Earlier data can be discarded.
+
+
+It is best to use PCRE_PARTIAL_HARD in this situation, because it does not
+treat the end of a segment as the end of the subject when matching \z, \Z,
+\b, \B, and $. Consider an unanchored pattern that matches dates:
re> /\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d/
data> The date is 23ja\P\P
Partial match: 23ja
At this stage, an application could discard the text preceding "23ja", add on
-text from the next segment, and call pcre_exec() again. Unlike
-pcre_dfa_exec(), the entire matching string must always be available, and
-the complete matching process occurs for each call, so more memory and more
+text from the next segment, and call the matching function again. Unlike the
+DFA matching functions, the entire matching string must always be available,
+and the complete matching process occurs for each call, so more memory and more
processing time is needed.
Note: If the pattern contains lookbehind assertions, or \K, or starts
-with \b or \B, the string that is returned for a partial match will include
+with \b or \B, the string that is returned for a partial match includes
characters that precede the partially matched string itself, because these must
be retained when adding on more characters for a subsequent matching attempt.
+However, in some cases you may need to retain even earlier characters, as
+discussed in the next section.
@@ -338,15 +352,33 @@
includes the effect of PCRE_NOTEOL.
-2. Lookbehind assertions at the start of a pattern are catered for in the
-offsets that are returned for a partial match. However, in theory, a lookbehind
-assertion later in the pattern could require even earlier characters to be
-inspected, and it might not have been reached when a partial match occurs. This
-is probably an extremely unlikely case; you could guard against it to a certain
-extent by always including extra characters at the start.
+2. Lookbehind assertions that have already been obeyed are catered for in the
+offsets that are returned for a partial match. However a lookbehind assertion
+later in the pattern could require even earlier characters to be inspected. You
+can handle this case by using the PCRE_INFO_MAXLOOKBEHIND option of the
+pcre_fullinfo() or pcre16_fullinfo() functions to obtain the length
+of the largest lookbehind in the pattern. This length is given in characters,
+not bytes. If you always retain at least that many characters before the
+partially matched string, all should be well. (Of course, near the start of the
+subject, fewer characters may be present; in that case all characters should be
+retained.)
+
+
+3. Because a partial match must always contain at least one character, what
+might be considered a partial match of an empty string actually gives a "no
+match" result. For example:
+
+ re> /c(?<=abc)x/
+ data> ab\P
+ No match
+
+If the next segment begins "cx", a match should be found, but this will only
+happen if characters from the previous segment are retained. For this reason, a
+"no match" result should be interpreted as "partial match of an empty string"
+when the pattern contains lookbehinds.
-3. Matching a subject string that is split into multiple segments may not
+4. Matching a subject string that is split into multiple segments may not
always produce exactly the same result as matching over one single long string,
especially when PCRE_PARTIAL_SOFT is used. The section "Partial Matching and
Word Boundaries" above describes an issue that arises if the pattern ends with
@@ -367,14 +399,14 @@
0: dogsbody
1: dog
-The first data line passes the string "dogsb" to pcre_exec(), setting the
-PCRE_PARTIAL_SOFT option. Although the string is a partial match for
-"dogsbody", the result is not PCRE_ERROR_PARTIAL, because the shorter string
-"dog" is a complete match. Similarly, when the subject is presented to
-pcre_dfa_exec() in several parts ("do" and "gsb" being the first two) the
-match stops when "dog" has been found, and it is not possible to continue. On
-the other hand, if "dogsbody" is presented as a single string,
-pcre_dfa_exec() finds both matches.
+The first data line passes the string "dogsb" to a standard matching function,
+setting the PCRE_PARTIAL_SOFT option. Although the string is a partial match
+for "dogsbody", the result is not PCRE_ERROR_PARTIAL, because the shorter
+string "dog" is a complete match. Similarly, when the subject is presented to
+a DFA matching function in several parts ("do" and "gsb" being the first two)
+the match stops when "dog" has been found, and it is not possible to continue.
+On the other hand, if "dogsbody" is presented as a single string, a DFA
+matching function finds both matches.
Because of these problems, it is best to use PCRE_PARTIAL_HARD when matching
@@ -388,10 +420,9 @@
data> gsb\R\P\P\D
Partial match: gsb
-4. Patterns that contain alternatives at the top level which do not all
-start with the same pattern item may not work as expected when
-PCRE_DFA_RESTART is used with pcre_dfa_exec(). For example, consider this
-pattern:
+5. Patterns that contain alternatives at the top level which do not all start
+with the same pattern item may not work as expected when PCRE_DFA_RESTART is
+used. For example, consider this pattern:
1234|3789
@@ -407,8 +438,8 @@
1234|ABCD
where no string can be a partial match for both alternatives. This is not a
-problem if pcre_exec() is used, because the entire match has to be rerun
-each time:
+problem if a standard matching function is used, because the entire match has
+to be rerun each time:
Of course, instead of using PCRE_DFA_RESTART, the same technique of re-running
-the entire match can also be used with pcre_dfa_exec(). Another
+the entire match can also be used with the DFA matching functions. Another
possibility is to work with two buffers. If a partial match at offset n
in the first buffer is followed by "no match" when PCRE_DFA_RESTART is used on
the second buffer, you can then try a new match starting at offset n+1 in
@@ -434,9 +465,9 @@
REVISION
The original operation of PCRE was on strings of one-byte characters. However,
-there is now also support for UTF-8 character strings. To use this,
-PCRE must be built to include UTF-8 support, and you must call
-pcre_compile() or pcre_compile2() with the PCRE_UTF8 option. There
-is also a special sequence that can be given at the start of a pattern:
+there is now also support for UTF-8 strings in the original library, and a
+second library that supports 16-bit and UTF-16 character strings. To use these
+features, PCRE must be built to include appropriate support. When using UTF
+strings you must either call the compiling function with the PCRE_UTF8 or
+PCRE_UTF16 option, or the pattern must start with one of these special
+sequences:
(*UTF8)
+ (*UTF16)
-Starting a pattern with this sequence is equivalent to setting the PCRE_UTF8
-option. This feature is not Perl-compatible. How setting UTF-8 mode affects
+Starting a pattern with such a sequence is equivalent to setting the relevant
+option. This feature is not Perl-compatible. How setting a UTF mode affects
pattern matching is mentioned in several places below. There is also a summary
-of UTF-8 features in the
-section on UTF-8 support
-in the main
-pcre
+of features in the
+pcreunicode
page.
Another special sequence that may appear at the start of a pattern or in
-combination with (*UTF8) is:
+combination with (*UTF8) or (*UTF16) is:
(*UCP)
@@ -96,13 +97,13 @@
The remainder of this document discusses the patterns that are supported by
-PCRE when its main matching function, pcre_exec(), is used.
-From release 6.0, PCRE offers a second matching function,
-pcre_dfa_exec(), which matches using a different algorithm that is not
-Perl-compatible. Some of the features discussed below are not available when
-pcre_dfa_exec() is used. The advantages and disadvantages of the
-alternative function, and how it differs from the normal function, are
-discussed in the
+PCRE when one its main matching functions, pcre_exec() (8-bit) or
+pcre16_exec() (16-bit), is used. PCRE also has alternative matching
+functions, pcre_dfa_exec() and pcre16_dfa_exec(), which match using
+a different algorithm that is not Perl-compatible. Some of the features
+discussed below are not available when DFA matching is used. The advantages and
+disadvantages of the alternative functions, and how they differ from the normal
+functions, are discussed in the
pcrematching
page.
@@ -128,9 +129,8 @@
(*ANYCRLF) any of the three above
(*ANY) all Unicode newline sequences
-These override the default and the options given to pcre_compile() or
-pcre_compile2(). For example, on a Unix system where LF is the default
-newline sequence, the pattern
+These override the default and the options given to the compiling function. For
+example, on a Unix system where LF is the default newline sequence, the pattern
(*CR)a.b
@@ -160,13 +160,13 @@
matches a portion of a subject string that is identical to itself. When
caseless matching is specified (the PCRE_CASELESS option), letters are matched
-independently of case. In UTF-8 mode, PCRE always understands the concept of
+independently of case. In a UTF mode, PCRE always understands the concept of
case for characters whose values are less than 128, so caseless matching is
always possible. For characters with higher values, the concept of case is
supported if PCRE is compiled with Unicode property support, but not otherwise.
If you want to use caseless matching for characters 128 and above, you must
ensure that PCRE is compiled with Unicode property support as well as with
-UTF-8 support.
+UTF support.
The power of regular expressions comes from the ability to include alternatives
@@ -222,15 +222,15 @@
particular, if you want to match a backslash, you write \\.
-In UTF-8 mode, only ASCII numbers and letters have any special meaning after a
+In a UTF mode, only ASCII numbers and letters have any special meaning after a
backslash. All other characters (in particular, those whose codepoints are
greater than 127) are treated as literals.
-If a pattern is compiled with the PCRE_EXTENDED option, whitespace in the
+If a pattern is compiled with the PCRE_EXTENDED option, white space in the
pattern (other than in a character class) and characters between a # outside
a character class and the next newline are ignored. An escaping backslash can
-be used to include a whitespace or # character as part of the pattern.
+be used to include a white space or # character as part of the pattern.
If you want to remove the special meaning from a sequence of characters, you
@@ -245,7 +245,11 @@
\Qabc\E\$\Qxyz\E abc$xyz abc$xyz
The \Q...\E sequence is recognized both inside and outside character classes.
-An isolated \E that is not preceded by \Q is ignored.
+An isolated \E that is not preceded by \Q is ignored. If \Q is not followed
+by \E later in the pattern, the literal interpretation continues to the end of
+the pattern (that is, \E is assumed at the end). If the isolated \Q is inside
+a character class, this causes an error, because the character class is not
+terminated.
Non-printing characters
@@ -260,30 +264,36 @@
\a alarm, that is, the BEL character (hex 07)
\cx "control-x", where x is any ASCII character
\e escape (hex 1B)
- \f formfeed (hex 0C)
+ \f form feed (hex 0C)
\n linefeed (hex 0A)
\r carriage return (hex 0D)
\t tab (hex 09)
\ddd character with octal code ddd, or back reference
\xhh character with hex code hh
- \x{hhh..} character with hex code hhh..
+ \x{hhh..} character with hex code hhh.. (non-JavaScript mode)
+ \uhhhh character with hex code hhhh (JavaScript mode only)
The precise effect of \cx is as follows: if x is a lower case letter, it
is converted to upper case. Then bit 6 of the character (hex 40) is inverted.
Thus \cz becomes hex 1A (z is 7A), but \c{ becomes hex 3B ({ is 7B), while
\c; becomes hex 7B (; is 3B). If the byte following \c has a value greater
than 127, a compile-time error occurs. This locks out non-ASCII characters in
-both byte mode and UTF-8 mode. (When PCRE is compiled in EBCDIC mode, all byte
-values are valid. A lower case letter is converted to upper case, and then the
-0xc0 bits are flipped.)
-
-
-After \x, from zero to two hexadecimal digits are read (letters can be in
-upper or lower case). Any number of hexadecimal digits may appear between \x{
-and }, but the value of the character code must be less than 256 in non-UTF-8
-mode, and less than 2**31 in UTF-8 mode. That is, the maximum value in
-hexadecimal is 7FFFFFFF. Note that this is bigger than the largest Unicode code
-point, which is 10FFFF.
+all modes. (When PCRE is compiled in EBCDIC mode, all byte values are valid. A
+lower case letter is converted to upper case, and then the 0xc0 bits are
+flipped.)
+
+
+By default, after \x, from zero to two hexadecimal digits are read (letters
+can be in upper or lower case). Any number of hexadecimal digits may appear
+between \x{ and }, but the character code is constrained as follows:
+
+ 8-bit non-UTF mode less than 0x100
+ 8-bit UTF-8 mode less than 0x10ffff and a valid codepoint
+ 16-bit non-UTF mode less than 0x10000
+ 16-bit UTF-16 mode less than 0x10ffff and a valid codepoint
+
+Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called
+"surrogate" codepoints).
If characters other than hexadecimal digits appear between \x{ and }, or if
@@ -292,9 +302,19 @@
following digits, giving a character whose value is zero.
+If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \x is
+as just described only when it is followed by two hexadecimal digits.
+Otherwise, it matches a literal "x" character. In JavaScript mode, support for
+code points greater than 256 is provided by \u, which must be followed by
+four hexadecimal digits; otherwise it matches a literal "u" character.
+Character codes specified by \u in JavaScript mode are constrained in the same
+was as those specified by \x in non-JavaScript mode.
+
+
Characters whose value is less than 256 can be defined by either of the two
-syntaxes for \x. There is no difference in the way they are handled. For
-example, \xdc is exactly the same as \x{dc}.
+syntaxes for \x (or by \u in JavaScript mode). There is no difference in the
+way they are handled. For example, \xdc is exactly the same as \x{dc} (or
+\u00dc in JavaScript mode).
After \0 up to two further octal digits are read. If there are fewer than two
@@ -317,9 +337,9 @@
Inside a character class, or if the decimal number is greater than 9 and there
have not been that many capturing subpatterns, PCRE re-reads up to three octal
digits following the backslash, and uses them to generate a data character. Any
-subsequent digits stand for themselves. In non-UTF-8 mode, the value of a
-character specified in octal must be less than \400. In UTF-8 mode, values up
-to \777 are permitted. For example:
+subsequent digits stand for themselves. The value of the character is
+constrained in the same way as characters specified in hexadecimal.
+For example:
\040 is another way of writing a space
\40 is the same, provided there are fewer than 40 previous capturing subpatterns
@@ -328,7 +348,7 @@
\011 is always a tab
\0113 is a tab followed by the character "3"
\113 might be a back reference, otherwise the character with octal code 113
- \377 might be a back reference, otherwise the byte consisting entirely of 1 bits
+ \377 might be a back reference, otherwise the value 255 (decimal)
\81 is either a back reference, or a binary zero followed by the two characters "8" and "1"
Note that octal values of 100 or greater must not be introduced by a leading
@@ -336,12 +356,25 @@
All the sequences that define a single character value can be used both inside
-and outside character classes. In addition, inside a character class, the
-sequence \b is interpreted as the backspace character (hex 08). The sequences
-\B, \N, \R, and \X are not special inside a character class. Like any other
-unrecognized escape sequences, they are treated as the literal characters "B",
-"N", "R", and "X" by default, but cause an error if the PCRE_EXTRA option is
-set. Outside a character class, these sequences have different meanings.
+and outside character classes. In addition, inside a character class, \b is
+interpreted as the backspace character (hex 08).
+
+
+\N is not allowed in a character class. \B, \R, and \X are not special
+inside a character class. Like other unrecognized escape sequences, they are
+treated as the literal characters "B", "R", and "X" by default, but cause an
+error if the PCRE_EXTRA option is set. Outside a character class, these
+sequences have different meanings.
+
+
+Unsupported escape sequences
+
+
+In Perl, the sequences \l, \L, \u, and \U are recognized by its string
+handler and used to modify the case of following characters. By default, PCRE
+does not support these escape sequences. However, if the PCRE_JAVASCRIPT_COMPAT
+option is set, \U matches a "U" character, and \u can be used to define a
+character by code point, as described in the previous section.
Absolute and relative back references
@@ -375,19 +408,20 @@
\d any decimal digit
\D any character that is not a decimal digit
- \h any horizontal whitespace character
- \H any character that is not a horizontal whitespace character
- \s any whitespace character
- \S any character that is not a whitespace character
- \v any vertical whitespace character
- \V any character that is not a vertical whitespace character
+ \h any horizontal white space character
+ \H any character that is not a horizontal white space character
+ \s any white space character
+ \S any character that is not a white space character
+ \v any vertical white space character
+ \V any character that is not a vertical white space character
\w any "word" character
\W any "non-word" character
There is also the single sequence \N, which matches a non-newline character.
This is the same as
the "." metacharacter
-when PCRE_DOTALL is not set.
+when PCRE_DOTALL is not set. Perl also uses \N to match characters by name;
+PCRE does not support this.
Each pair of lower and upper case escape sequences partitions the complete set
@@ -418,9 +452,9 @@
Unicode is discouraged.
-By default, in UTF-8 mode, characters with values greater than 128 never match
+By default, in a UTF mode, characters with values greater than 128 never match
\d, \s, or \w, and always match \D, \S, and \W. These sequences retain
-their original meanings from before UTF-8 support was available, mainly for
+their original meanings from before UTF support was available, mainly for
efficiency reasons. However, if PCRE is compiled with Unicode property support,
and the PCRE_UCP option is set, the behaviour is changed so that Unicode
properties are used to determine character types, as follows:
@@ -438,9 +472,8 @@
The sequences \h, \H, \v, and \V are features that were added to Perl at
release 5.10. In contrast to the other sequences, which match only ASCII
-characters by default, these always match certain high-valued codepoints in
-UTF-8 mode, whether or not PCRE_UCP is set. The horizontal space characters
-are:
+characters by default, these always match certain high-valued codepoints,
+whether or not PCRE_UCP is set. The horizontal space characters are:
U+0009 Horizontal tab
U+0020 Space
@@ -466,19 +499,22 @@
U+000A Linefeed
U+000B Vertical tab
- U+000C Formfeed
+ U+000C Form feed
U+000D Carriage return
U+0085 Next line
U+2028 Line separator
U+2029 Paragraph separator
-
-
+
+In 8-bit, non-UTF-8 mode, only the characters with codepoints less than 256 are
+relevant.
+
Newline sequences
Outside a character class, by default, the escape sequence \R matches any
-Unicode newline sequence. In non-UTF-8 mode \R is equivalent to the following:
+Unicode newline sequence. In 8-bit non-UTF-8 mode \R is equivalent to the
+following:
(?>\r\n|\n|\x0b|\f|\r|\x85)
@@ -486,12 +522,12 @@
below.
This particular group matches either the two-character sequence CR followed by
LF, or one of the single characters LF (linefeed, U+000A), VT (vertical tab,
-U+000B), FF (formfeed, U+000C), CR (carriage return, U+000D), or NEL (next
+U+000B), FF (form feed, U+000C), CR (carriage return, U+000D), or NEL (next
line, U+0085). The two-character sequence is treated as a single unit that
cannot be split.
-In UTF-8 mode, two additional characters whose codepoints are greater than 255
+In other modes, two additional characters whose codepoints are greater than 255
are added: LS (line separator, U+2028) and PS (paragraph separator, U+2029).
Unicode character property support is not needed for these characters to be
recognized.
@@ -508,19 +544,19 @@
(*BSR_ANYCRLF) CR, LF, or CRLF only
(*BSR_UNICODE) any Unicode newline sequence
-These override the default and the options given to pcre_compile() or
-pcre_compile2(), but they can be overridden by options given to
-pcre_exec() or pcre_dfa_exec(). Note that these special settings,
-which are not Perl-compatible, are recognized only at the very start of a
-pattern, and that they must be in upper case. If more than one of them is
-present, the last one is used. They can be combined with a change of newline
-convention; for example, a pattern can start with:
+These override the default and the options given to the compiling function, but
+they can themselves be overridden by options given to a matching function. Note
+that these special settings, which are not Perl-compatible, are recognized only
+at the very start of a pattern, and that they must be in upper case. If more
+than one of them is present, the last one is used. They can be combined with a
+change of newline convention; for example, a pattern can start with:
(*ANY)(*BSR_ANYCRLF)
-They can also be combined with the (*UTF8) or (*UCP) special sequences. Inside
-a character class, \R is treated as an unrecognized escape sequence, and so
-matches the letter "R" by default, but causes an error if PCRE_EXTRA is set.
+They can also be combined with the (*UTF8), (*UTF16), or (*UCP) special
+sequences. Inside a character class, \R is treated as an unrecognized escape
+sequence, and so matches the letter "R" by default, but causes an error if
+PCRE_EXTRA is set.
Unicode character properties
@@ -528,7 +564,7 @@
When PCRE is built with Unicode character property support, three additional
escape sequences that match characters with specific properties are available.
-When not in UTF-8 mode, these sequences are of course limited to testing
+When in 8-bit non-UTF-8 mode, these sequences are of course limited to testing
characters whose codepoints are less than 256, but they do work in this mode.
The extra escape sequences are:
The Cs (Surrogate) property applies only to characters in the range U+D800 to
-U+DFFF. Such characters are not valid in UTF-8 strings (see RFC 3629) and so
-cannot be tested by PCRE, unless UTF-8 validity checking has been turned off
-(see the discussion of PCRE_NO_UTF8_CHECK in the
+U+DFFF. Such characters are not valid in Unicode strings and so
+cannot be tested by PCRE, unless UTF validity checking has been turned off
+(see the discussion of PCRE_NO_UTF8_CHECK and PCRE_NO_UTF16_CHECK in the
pcreapi
page). Perl does not support the Cs property.
@@ -749,15 +795,18 @@
(see below).
Characters with the "mark" property are typically accents that affect the
preceding character. None of them have codepoints less than 256, so in
-non-UTF-8 mode \X matches any one character.
+8-bit non-UTF-8 mode \X matches any one character.
+
+
+Note that recent versions of Perl have changed \X to match what Unicode calls
+an "extended grapheme cluster", which has a more complicated definition.
Matching characters by Unicode property is not fast, because PCRE has to search
a structure that contains data for over fifteen thousand characters. That is
why the traditional escape sequences such as \d and \w do not use Unicode
properties in PCRE by default, though you can make them do so by setting the
-PCRE_UCP option for pcre_compile() or by starting the pattern with
-(*UCP).
+PCRE_UCP option or by starting the pattern with (*UCP).
PCRE's additional properties
@@ -775,7 +824,7 @@
Xwd Any Perl "word" character
Xan matches characters that have either the L (letter) or the N (number)
-property. Xps matches the characters tab, linefeed, vertical tab, formfeed, or
+property. Xps matches the characters tab, linefeed, vertical tab, form feed, or
carriage return, and any other character that has the Z (separator) property.
Xsp is the same as Xps, except that vertical tab is excluded. Xwd matches the
same characters as Xan, plus underscore.
@@ -836,7 +885,7 @@
A word boundary is a position in the subject string where the current character
and the previous character do not both match \w or \W (i.e. one matches
\w and the other matches \W), or the start or end of the string if the
-first or last character matches \w, respectively. In UTF-8 mode, the meanings
+first or last character matches \w, respectively. In a UTF mode, the meanings
of \w and \W can be changed by setting the PCRE_UCP option. When this is
done, it also affects \b and \B. Neither PCRE nor Perl has a separate "start
of word" or "end of word" metasequence. However, whatever follows \b normally
@@ -933,7 +982,7 @@
Outside a character class, a dot in the pattern matches any one character in
the subject string except (by default) a character that signifies the end of a
-line. In UTF-8 mode, the matched character may be more than one byte long.
+line.
When a line ending is defined as a single character, dot never matches that
@@ -957,22 +1006,47 @@
The escape sequence \N behaves like a dot, except that it is not affected by
the PCRE_DOTALL option. In other words, it matches any character except one
-that signifies the end of a line.
+that signifies the end of a line. Perl also uses \N to match characters by
+name; PCRE does not support this.
-Outside a character class, the escape sequence \C matches any one byte, both
-in and out of UTF-8 mode. Unlike a dot, it always matches any line-ending
-characters. The feature is provided in Perl in order to match individual bytes
-in UTF-8 mode. Because it breaks up UTF-8 characters into individual bytes, the
-rest of the string may start with a malformed UTF-8 character. For this reason,
-the \C escape sequence is best avoided.
+Outside a character class, the escape sequence \C matches any one data unit,
+whether or not a UTF mode is set. In the 8-bit library, one data unit is one
+byte; in the 16-bit library it is a 16-bit unit. Unlike a dot, \C always
+matches line-ending characters. The feature is provided in Perl in order to
+match individual bytes in UTF-8 mode, but it is unclear how it can usefully be
+used. Because \C breaks up characters into individual data units, matching one
+unit with \C in a UTF mode means that the rest of the string may start with a
+malformed UTF character. This has undefined results, because PCRE assumes that
+it is dealing with valid UTF strings (and by default it checks this at the
+start of processing unless the PCRE_NO_UTF8_CHECK or PCRE_NO_UTF16_CHECK option
+is used).
PCRE does not allow \C to appear in lookbehind assertions
-(described below),
-because in UTF-8 mode this would make it impossible to calculate the length of
+(described below)
+in a UTF mode, because this would make it impossible to calculate the length of
the lookbehind.
+
+
+In general, the \C escape sequence is best avoided. However, one
+way of using it that avoids the problem of malformed UTF characters is to use a
+lookahead to check the length of the next character, as in this pattern, which
+could be used with a UTF-8 string (ignore white space and line breaks):
+
+A group that starts with (?| resets the capturing parentheses numbers in each
+alternative (see
+"Duplicate Subpattern Numbers"
+below). The assertions at the start of each branch check the next UTF-8
+character for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The
+character's individual bytes are then captured by the appropriate number of
+groups.
SQUARE BRACKETS AND CHARACTER CLASSES
@@ -984,12 +1058,12 @@
(after an initial circumflex, if present) or escaped with a backslash.
-A character class matches a single character in the subject. In UTF-8 mode, the
-character may be more than one byte long. A matched character must be in the
-set of characters defined by the class, unless the first character in the class
-definition is a circumflex, in which case the subject character must not be in
-the set defined by the class. If a circumflex is actually required as a member
-of the class, ensure it is not the first character, or escape it with a
+A character class matches a single character in the subject. In a UTF mode, the
+character may be more than one data unit long. A matched character must be in
+the set of characters defined by the class, unless the first character in the
+class definition is a circumflex, in which case the subject character must not
+be in the set defined by the class. If a circumflex is actually required as a
+member of the class, ensure it is not the first character, or escape it with a
backslash.
@@ -1002,20 +1076,21 @@
string.
-In UTF-8 mode, characters with values greater than 255 can be included in a
-class as a literal string of bytes, or by using the \x{ escaping mechanism.
+In UTF-8 (UTF-16) mode, characters with values greater than 255 (0xffff) can be
+included in a class as a literal string of data units, or by using the \x{
+escaping mechanism.
When caseless matching is set, any letters in a class represent both their
upper case and lower case versions, so for example, a caseless [aeiou] matches
"A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a
-caseful version would. In UTF-8 mode, PCRE always understands the concept of
+caseful version would. In a UTF mode, PCRE always understands the concept of
case for characters whose values are less than 128, so caseless matching is
always possible. For characters with higher values, the concept of case is
supported if PCRE is compiled with Unicode property support, but not otherwise.
-If you want to use caseless matching in UTF8-mode for characters 128 and above,
-you must ensure that PCRE is compiled with Unicode property support as well as
-with UTF-8 support.
+If you want to use caseless matching in a UTF mode for characters 128 and
+above, you must ensure that PCRE is compiled with Unicode property support as
+well as with UTF support.
Characters that might indicate line breaks are never treated in any special way
@@ -1041,16 +1116,15 @@
Ranges operate in the collating sequence of character values. They can also be
-used for characters specified numerically, for example [\000-\037]. In UTF-8
-mode, ranges can include characters whose values are greater than 255, for
-example [\x{100}-\x{2ff}].
+used for characters specified numerically, for example [\000-\037]. Ranges
+can include any characters that are valid for the current mode.
If a range that includes letters is used when caseless matching is set, it
matches the letters in either case. For example, [W-c] is equivalent to
-[][\\^_`wxyzabc], matched caselessly, and in non-UTF-8 mode, if character
+[][\\^_`wxyzabc], matched caselessly, and in a non-UTF mode, if character
tables for a French locale are in use, [\xc8-\xcb] matches accented E
-characters in both cases. In UTF-8 mode, PCRE supports the concept of case for
+characters in both cases. In UTF modes, PCRE supports the concept of case for
characters with values greater than 128 only when it is compiled with Unicode
property support.
@@ -1058,7 +1132,7 @@
The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v,
\V, \w, and \W may appear in a character class, and add the characters that
they match to the class. For example, [\dABCDEF] matches any hexadecimal
-digit. In UTF-8 mode, the PCRE_UCP option affects the meanings of \d, \s, \w
+digit. In UTF modes, the PCRE_UCP option affects the meanings of \d, \s, \w
and their upper case partners, just as it does when they appear outside a
character class, as described in the section entitled
"Generic character types"
@@ -1127,7 +1201,7 @@
supported, and an error is given if they are encountered.
-By default, in UTF-8 mode, characters with values greater than 128 do not match
+By default, in UTF modes, characters with values greater than 128 do not match
any of the POSIX character classes. However, if the PCRE_UCP option is passed
to pcre_compile(), some of the classes are changed so that Unicode
character properties are used. This is achieved by replacing the POSIX classes
@@ -1212,14 +1286,14 @@
Note: There are other PCRE-specific options that can be set by the
-application when the compile or match functions are called. In some cases the
-pattern can contain special leading sequences such as (*CRLF) to override what
-the application has set or what has been defaulted. Details are given in the
-section entitled
+application when the compiling or matching functions are called. In some cases
+the pattern can contain special leading sequences such as (*CRLF) to override
+what the application has set or what has been defaulted. Details are given in
+the section entitled
"Newline sequences"
-above. There are also the (*UTF8) and (*UCP) leading sequences that can be used
-to set UTF-8 and Unicode property modes; they are equivalent to setting the
-PCRE_UTF8 and the PCRE_UCP options, respectively.
+above. There are also the (*UTF8), (*UTF16), and (*UCP) leading sequences that
+can be used to set UTF and Unicode property modes; they are equivalent to
+setting the PCRE_UTF8, PCRE_UTF16, and the PCRE_UCP options, respectively.
@@ -1237,10 +1311,14 @@
2. It sets up the subpattern as a capturing subpattern. This means that, when
the whole pattern matches, that portion of the subject string that matched the
-subpattern is passed back to the caller via the ovector argument of
-pcre_exec(). Opening parentheses are counted from left to right (starting
-from 1) to obtain numbers for the capturing subpatterns. For example, if the
-string "the red king" is matched against the pattern
+subpattern is passed back to the caller via the ovector argument of the
+matching function. (This applies only to the traditional matching functions;
+the DFA matching functions do not support capturing.)
+
+
+Opening parentheses are counted from left to right (starting from 1) to obtain
+numbers for the capturing subpatterns. For example, if the string "the red
+king" is matched against the pattern
the ((red|white) (king|queen))
@@ -1302,9 +1380,9 @@
/(?|(abc)|(def))\1/
-In contrast, a recursive or "subroutine" call to a numbered subpattern always
-refers to the first one in the pattern with the given number. The following
-pattern matches "abcabc" or "defabc":
+In contrast, a subroutine call to a numbered subpattern always refers to the
+first one in the pattern with the given number. The following pattern matches
+"abcabc" or "defabc":
/(?|(abc)|(def))(?1)/
@@ -1400,13 +1478,13 @@
a literal data character
the dot metacharacter
the \C escape sequence
- the \X escape sequence (in UTF-8 mode with Unicode properties)
+ the \X escape sequence
the \R escape sequence
an escape such as \d or \pL that matches a single character
a character class
a back reference (see next section)
- a parenthesized subpattern (unless it is an assertion)
- a recursive or "subroutine" call to a subpattern
+ a parenthesized subpattern (including assertions)
+ a subroutine call to a subpattern (recursive or otherwise)
The general repetition quantifier specifies a minimum and maximum number of
permitted matches, by giving the two numbers in curly brackets (braces),
@@ -1432,11 +1510,11 @@
quantifier, but a literal string of four characters.
-In UTF-8 mode, quantifiers apply to UTF-8 characters rather than to individual
-bytes. Thus, for example, \x{100}{2} matches two UTF-8 characters, each of
-which is represented by a two-byte sequence. Similarly, when Unicode property
-support is available, \X{3} matches three Unicode extended sequences, each of
-which may be several bytes long (and they may be of different lengths).
+In UTF modes, quantifiers apply to characters rather than to individual data
+units. Thus, for example, \x{100}{2} matches two characters, each of
+which is represented by a two-byte sequence in a UTF-8 string. Similarly,
+\X{3} matches three Unicode extended sequences, each of which may be several
+data units long (and they may be of different lengths).
The quantifier {0} is permitted, causing the expression to behave as if the
@@ -1753,7 +1831,7 @@
following a backslash are taken as part of a potential back reference number.
If the pattern continues with a digit character, some delimiter must be used to
terminate the back reference. If the PCRE_EXTENDED option is set, this can be
-whitespace. Otherwise, the \g{ syntax or an empty comment (see
+white space. Otherwise, the \g{ syntax or an empty comment (see
"Comments"
below) can be used.
@@ -1796,12 +1874,32 @@
except that it does not cause the current matching position to be changed.
-Assertion subpatterns are not capturing subpatterns, and may not be repeated,
-because it makes no sense to assert the same thing several times. If any kind
-of assertion contains capturing subpatterns within it, these are counted for
-the purposes of numbering the capturing subpatterns in the whole pattern.
-However, substring capturing is carried out only for positive assertions,
-because it does not make sense for negative assertions.
+Assertion subpatterns are not capturing subpatterns. If such an assertion
+contains capturing subpatterns within it, these are counted for the purposes of
+numbering the capturing subpatterns in the whole pattern. However, substring
+capturing is carried out only for positive assertions, because it does not make
+sense for negative assertions.
+
+
+For compatibility with Perl, assertion subpatterns may be repeated; though
+it makes no sense to assert the same thing several times, the side effect of
+capturing parentheses may occasionally be useful. In practice, there only three
+cases:
+
+
+(1) If the quantifier is {0}, the assertion is never obeyed during matching.
+However, it may contain internal capturing parenthesized groups that are called
+from elsewhere via the
+subroutine mechanism.
+
+
+(2) If quantifier is {0,n} where n is greater than zero, it is treated as if it
+were {0,1}. At run time, the rest of the pattern match is tried with and
+without the assertion, the order depending on the greediness of the quantifier.
+
+
+(3) If the minimum repetition is greater than zero, the quantifier is ignored.
+The assertion is obeyed just once when encountered during matching.
-PCRE does not allow the \C escape (which matches a single byte in UTF-8 mode)
-to appear in lookbehind assertions, because it makes it impossible to calculate
-the length of the lookbehind. The \X and \R escapes, which can match
-different numbers of bytes, are also not permitted.
+In a UTF mode, PCRE does not allow the \C escape (which matches a single data
+unit even in a UTF mode) to appear in lookbehind assertions, because it makes
+it impossible to calculate the length of the lookbehind. The \X and \R
+escapes, which can match different numbers of data units, are also not
+permitted.
"Subroutine"
@@ -2071,10 +2170,10 @@
name DEFINE, the condition is always false. In this case, there may be only one
alternative in the subpattern. It is always skipped if control reaches this
point in the pattern; the idea of DEFINE is that it can be used to define
-"subroutines" that can be referenced from elsewhere. (The use of
-"subroutines"
+subroutines that can be referenced from elsewhere. (The use of
+subroutines
is described below.) For example, a pattern to match an IPv4 address such as
-"192.168.23.245" could be written like this (ignore whitespace and line
+"192.168.23.245" could be written like this (ignore white space and line
breaks):
(?(DEFINE) (?<byte> 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
@@ -2120,7 +2219,7 @@
option is set, an unescaped # character also introduces a comment, which in
this case continues to immediately after the next newline character or
character sequence in the pattern. Which characters are interpreted as newlines
-is controlled by the options passed to pcre_compile() or by a special
+is controlled by the options passed to a compiling function or by a special
sequence at the start of the pattern, as described in the section entitled
"Newline conventions"
above. Note that the end of this type of comment is a literal newline sequence
@@ -2162,9 +2261,9 @@
A special item that consists of (? followed by a number greater than zero and a
-closing parenthesis is a recursive call of the subpattern of the given number,
-provided that it occurs inside that subpattern. (If not, it is a
-"subroutine"
+closing parenthesis is a recursive subroutine call of the subpattern of the
+given number, provided that it occurs inside that subpattern. (If not, it is a
+non-recursive subroutine
call, which is described in the next section.) The special item (?R) or (?0) is
a recursive call of the entire regular expression.
@@ -2200,7 +2299,7 @@
It is also possible to refer to subsequently opened parentheses, by writing
references such as (?+2). However, these cannot be recursive because the
reference is not inside the parentheses that are referenced. They are always
-"subroutine"
+non-recursive subroutine
calls, as described in the next section.
@@ -2237,8 +2336,8 @@
the value for the inner capturing parentheses (numbered 2) is "ef", which is
the last value taken on at the top level. If a capturing subpattern is not
-matched at the top level, its final value is unset, even if it is (temporarily)
-set at a deeper level.
+matched at the top level, its final captured value is unset, even if it was
+(temporarily) set at a deeper level during the matching process.
If there are more than 15 capturing parentheses in a pattern, PCRE has to
@@ -2259,15 +2358,16 @@
is the actual recursive call.
-Recursion difference from Perl
+Differences in recursion processing between PCRE and Perl
-In PCRE (like Python, but unlike Perl), a recursive subpattern call is always
-treated as an atomic group. That is, once it has matched some of the subject
-string, it is never re-entered, even if it contains untried alternatives and
-there is a subsequent matching failure. This can be illustrated by the
-following pattern, which purports to match a palindromic string that contains
-an odd number of characters (for example, "a", "aba", "abcba", "abcdcba"):
+Recursion processing in PCRE differs from Perl in two important ways. In PCRE
+(like Python, but unlike Perl), a recursive subpattern call is always treated
+as an atomic group. That is, once it has matched some of the subject string, it
+is never re-entered, even if it contains untried alternatives and there is a
+subsequent matching failure. This can be illustrated by the following pattern,
+which purports to match a palindromic string that contains an odd number of
+characters (for example, "a", "aba", "abcba", "abcdcba"):
^(.|(.)(?1)\2)$
@@ -2332,12 +2432,28 @@
PCRE finds the palindrome "aba" at the start, then fails at top level because
the end of the string does not follow. Once again, it cannot jump back into the
recursion to try other alternatives, so the entire match fails.
+
+
+The second way in which PCRE and Perl differ in their recursion processing is
+in the handling of captured values. In Perl, when a subpattern is called
+recursively or as a subpattern (see the next section), it has no access to any
+values that were captured outside the recursion, whereas in PCRE these values
+can be referenced. Consider this pattern:
+
+ ^(.)(\1|a(?2))
+
+In PCRE, this pattern matches "bab". The first capturing parentheses match "b",
+then in the second group, when the back reference \1 fails to match "b", the
+second alternative matches "a" and then recurses. In the recursion, \1 does
+now match "b" and so the whole match succeeds. In Perl, the pattern fails to
+match because inside the recursive call \1 cannot access the externally set
+value.
SUBPATTERNS AS SUBROUTINES
-If the syntax for a recursive subpattern reference (either by number or by
+If the syntax for a recursive subpattern call (either by number or by
name) is used outside the parentheses to which it refers, it operates like a
-subroutine in a programming language. The "called" subpattern may be defined
+subroutine in a programming language. The called subpattern may be defined
before or after the reference. A numbered reference can be absolute or
relative, as in these examples:
@@ -2358,16 +2474,16 @@
strings. Another example is given in the discussion of DEFINE above.
-Like recursive subpatterns, a subroutine call is always treated as an atomic
-group. That is, once it has matched some of the subject string, it is never
-re-entered, even if it contains untried alternatives and there is a subsequent
-matching failure. Any capturing parentheses that are set during the subroutine
-call revert to their previous values afterwards.
+All subroutine calls, whether recursive or not, are always treated as atomic
+groups. That is, once a subroutine has matched some of the subject string, it
+is never re-entered, even if it contains untried alternatives and there is a
+subsequent matching failure. Any capturing parentheses that are set during the
+subroutine call revert to their previous values afterwards.
-When a subpattern is used as a subroutine, processing options such as
-case-independence are fixed when the subpattern is defined. They cannot be
-changed for different calls. For example, consider this pattern:
+Processing options such as case-independence are fixed when a subpattern is
+defined, so if it is used as a subroutine, such options cannot be changed for
+different calls. For example, consider this pattern:
(abc)(?i:(?-1))
@@ -2402,8 +2518,9 @@
PCRE provides a similar feature, but of course it cannot obey arbitrary Perl
code. The feature is called "callout". The caller of PCRE provides an external
-function by putting its entry point in the global variable pcre_callout.
-By default, this variable contains NULL, which disables all calling out.
+function by putting its entry point in the global variable pcre_callout
+(8-bit library) or pcre16_callout (16-bit library). By default, this
+variable contains NULL, which disables all calling out.
Within a regular expression, (?C) indicates the points at which the external
@@ -2413,17 +2530,17 @@
(?C1)abc(?C2)def
-If the PCRE_AUTO_CALLOUT flag is passed to pcre_compile(), callouts are
+If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, callouts are
automatically installed before each item in the pattern. They are all numbered
255.
-During matching, when PCRE reaches a callout point (and pcre_callout is
-set), the external function is called. It is provided with the number of the
-callout, the position in the pattern, and, optionally, one item of data
-originally supplied by the caller of pcre_exec(). The callout function
-may cause matching to proceed, to backtrack, or to fail altogether. A complete
-description of the interface to the callout function is given in the
+During matching, when PCRE reaches a callout point, the external function is
+called. It is provided with the number of the callout, the position in the
+pattern, and, optionally, one item of data originally supplied by the caller of
+the matching function. The callout function may cause matching to proceed, to
+backtrack, or to fail altogether. A complete description of the interface to
+the callout function is given in the
pcrecallout
documentation.
@@ -2437,26 +2554,35 @@
Since these verbs are specifically related to backtracking, most of them can be
-used only when the pattern is to be matched using pcre_exec(), which uses
-a backtracking algorithm. With the exception of (*FAIL), which behaves like a
-failing negative assertion, they cause an error if encountered by
-pcre_dfa_exec().
+used only when the pattern is to be matched using one of the traditional
+matching functions, which use a backtracking algorithm. With the exception of
+(*FAIL), which behaves like a failing negative assertion, they cause an error
+if encountered by a DFA matching function.
-If any of these verbs are used in an assertion or subroutine subpattern
-(including recursive subpatterns), their effect is confined to that subpattern;
-it does not extend to the surrounding pattern. Note that such subpatterns are
-processed as anchored at the point where they are tested.
+If any of these verbs are used in an assertion or in a subpattern that is
+called as a subroutine (whether or not recursively), their effect is confined
+to that subpattern; it does not extend to the surrounding pattern, with one
+exception: the name from a *(MARK), (*PRUNE), or (*THEN) that is encountered in
+a successful positive assertion is passed back when a match succeeds
+(compare capturing parentheses in assertions). Note that such subpatterns are
+processed as anchored at the point where they are tested. Note also that Perl's
+treatment of subroutines and assertions is different in some cases.
The new verbs make use of what was previously invalid syntax: an opening
parenthesis followed by an asterisk. They are generally of the form
(*VERB) or (*VERB:NAME). Some may take either form, with differing behaviour,
-depending on whether or not an argument is present. An name is a sequence of
-letters, digits, and underscores. If the name is empty, that is, if the closing
-parenthesis immediately follows the colon, the effect is as if the colon were
-not there. Any number of these verbs may occur in a pattern.
-
+depending on whether or not an argument is present. A name is any sequence of
+characters that does not include a closing parenthesis. The maximum length of
+name is 255 in the 8-bit library and 65535 in the 16-bit library. If the name
+is empty, that is, if the closing parenthesis immediately follows the colon,
+the effect is as if the colon were not there. Any number of these verbs may
+occur in a pattern.
+
+
+Optimizations that affect backtracking verbs
+
PCRE contains some optimizations that are used to speed up matching by running
some checks at the start of each match attempt. For example, it may know the
@@ -2465,7 +2591,16 @@
included backtracking verbs will not, of course, be processed. You can suppress
the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option
when calling pcre_compile() or pcre_exec(), or by starting the
-pattern with (*NO_START_OPT).
+pattern with (*NO_START_OPT). There is more discussion of this option in the
+section entitled
+"Option bits for pcre_exec()"
+in the
+pcreapi
+documentation.
+
+
+Experiments with Perl suggest that it too has similar optimizations, sometimes
+leading to anomalous results.
Verbs that act immediately
@@ -2477,9 +2612,10 @@
(*ACCEPT)
This verb causes the match to end successfully, skipping the remainder of the
-pattern. When inside a recursion, only the innermost pattern is ended
-immediately. If (*ACCEPT) is inside capturing parentheses, the data so far is
-captured. (This feature was added to PCRE at release 8.00.) For example:
+pattern. However, when it is inside a subpattern that is called as a
+subroutine, only that subpattern is ended successfully. Matching then continues
+at the outer level. If (*ACCEPT) is inside capturing parentheses, the data so
+far is captured. For example:
A((?:A|B(*ACCEPT)|C)D)
@@ -2488,7 +2624,7 @@
(*FAIL) or (*F)
-This verb causes the match to fail, forcing backtracking to occur. It is
+This verb causes a matching failure, forcing backtracking to occur. It is
equivalent to (?!) but easier to read. The Perl documentation notes that it is
probably useful only when combined with (?{}) or (??{}). Those are, of course,
Perl features that are not present in PCRE. The nearest equivalent is the
@@ -2513,17 +2649,16 @@
(*MARK) as you like in a pattern, and their names do not have to be unique.
-When a match succeeds, the name of the last-encountered (*MARK) is passed back
-to the caller via the pcre_extra data structure, as described in the
-section on pcre_extra
+When a match succeeds, the name of the last-encountered (*MARK) on the matching
+path is passed back to the caller as described in the section entitled
+"Extra data for pcre_exec()"
in the
pcreapi
-documentation. No data is returned for a partial match. Here is an example of
-pcretest output, where the /K modifier requests the retrieval and
-outputting of (*MARK) data:
+documentation. Here is an example of pcretest output, where the /K
+modifier requests the retrieval and outputting of (*MARK) data:
-A name may also be returned after a failed match if the final path through the
-pattern involves (*MARK). However, unless (*MARK) used in conjunction with
-(*COMMIT), this is unlikely to happen for an unanchored pattern because, as the
-starting point for matching is advanced, the final check is often with an empty
-string, causing a failure before (*MARK) is reached. For example:
-
- /X(*MARK:A)Y|X(*MARK:B)Z/K
- XP
- No match
-
-There are three potential starting points for this match (starting with X,
-starting with P, and with an empty string). If the pattern is anchored, the
-result is different:
+If (*MARK) is encountered in a positive assertion, its name is recorded and
+passed back if it is the last-encountered. This does not happen for negative
+assertions.
+
+
+After a partial match or a failed match, the name of the last encountered
+(*MARK) in the entire match process is returned. For example:
- /^X(*MARK:A)Y|^X(*MARK:B)Z/K
- XP
+ re> /X(*MARK:A)Y|X(*MARK:B)Z/K
+ data> XP
No match, mark = B
-PCRE's start-of-match optimizations can also interfere with this. For example,
-if, as a result of a call to pcre_study(), it knows the minimum
-subject length for a match, a shorter subject will not be scanned at all.
+Note that in this unanchored example the mark is retained from the match
+attempt that started at the letter "X" in the subject. Subsequent match
+attempts starting at "P" and then with an empty string do not get as far as the
+(*MARK) item, but nevertheless do not reset it.
-Note that similar anomalies (though different in detail) exist in Perl, no
-doubt for the same reasons. The use of (*MARK) data after a failed match of an
-unanchored pattern is not recommended, unless (*COMMIT) is involved.
+If you are interested in (*MARK) values after failed matches, you should
+probably set the PCRE_NO_START_OPTIMIZE option
+(see above)
+to ensure that the match is always attempted.
Verbs that act after backtracking
@@ -2600,8 +2731,8 @@
unless PCRE's start-of-match optimizations are turned off, as shown in this
pcretest example:
- /(*COMMIT)abc/
- xyzabc
+ re> /(*COMMIT)abc/
+ data> xyzabc
0: abc
xyzabc\Y
No match
@@ -2622,10 +2753,8 @@
the right, backtracking cannot cross (*PRUNE). In simple cases, the use of
(*PRUNE) is just an alternative to an atomic group or possessive quantifier,
but there are some uses of (*PRUNE) that cannot be expressed in any other way.
-The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE) when the
-match fails completely; the name is passed back if this is the final attempt.
-(*PRUNE:NAME) does not pass back a name if the match succeeds. In an anchored
-pattern (*PRUNE) has the same effect as (*COMMIT).
+The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an
+anchored pattern (*PRUNE) has the same effect as (*COMMIT).
(*SKIP)
@@ -2651,48 +2780,85 @@
searched for the most recent (*MARK) that has the same name. If one is found,
the "bumpalong" advance is to the subject position that corresponds to that
(*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with a
-matching name is found, normal "bumpalong" of one character happens (the
-(*SKIP) is ignored).
+matching name is found, the (*SKIP) is ignored.
(*THEN) or (*THEN:NAME)
-This verb causes a skip to the next alternation in the innermost enclosing
-group if the rest of the pattern does not match. That is, it cancels pending
-backtracking, but only within the current alternation. Its name comes from the
-observation that it can be used for a pattern-based if-then-else block:
+This verb causes a skip to the next innermost alternative if the rest of the
+pattern does not match. That is, it cancels pending backtracking, but only
+within the current alternative. Its name comes from the observation that it can
+be used for a pattern-based if-then-else block:
If the COND1 pattern matches, FOO is tried (and possibly further items after
-the end of the group if FOO succeeds); on failure the matcher skips to the
+the end of the group if FOO succeeds); on failure, the matcher skips to the
second alternative and tries COND2, without backtracking into COND1. The
-behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN) if the
-overall match fails. If (*THEN) is not directly inside an alternation, it acts
-like (*PRUNE).
+behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN).
+If (*THEN) is not inside an alternation, it acts like (*PRUNE).
+
+
+Note that a subpattern that does not contain a | character is just a part of
+the enclosing alternative; it is not a nested alternation with only one
+alternative. The effect of (*THEN) extends beyond such a subpattern to the
+enclosing alternative. Consider this pattern, where A, B, etc. are complex
+pattern fragments that do not contain any | characters at this level:
+
+ A (B(*THEN)C) | D
+
+If A and B are matched, but there is a failure in C, matching does not
+backtrack into A; instead it moves to the next alternative, that is, D.
+However, if the subpattern containing (*THEN) is given an alternative, it
+behaves differently:
+
+ A (B(*THEN)C | (*FAIL)) | D
+
+The effect of (*THEN) is now confined to the inner subpattern. After a failure
+in C, matching moves to (*FAIL), which causes the whole subpattern to fail
+because there are no more alternatives to try. In this case, matching does now
+backtrack into A.
+
+
+Note also that a conditional subpattern is not considered as having two
+alternatives, because only one is ever used. In other words, the | character in
+a conditional subpattern has a different meaning. Ignoring white space,
+consider:
+
+ ^.*? (?(?=a) a | b(*THEN)c )
+
+If the subject is "ba", this pattern does not match. Because .*? is ungreedy,
+it initially matches zero characters. The condition (?=a) then fails, the
+character "b" is matched, but "c" is not. At this point, matching does not
+backtrack to .*? as might perhaps be expected from the presence of the |
+character. The conditional subpattern is part of the single alternative that
+comprises the whole pattern, and so the match fails. (If there was a backtrack
+into .*?, allowing it to match "b", the match would succeed.)
-The above verbs provide four different "strengths" of control when subsequent
-matching fails. (*THEN) is the weakest, carrying on the match at the next
-alternation. (*PRUNE) comes next, failing the match at the current starting
-position, but allowing an advance to the next character (for an unanchored
-pattern). (*SKIP) is similar, except that the advance may be more than one
-character. (*COMMIT) is the strongest, causing the entire match to fail.
+The verbs just described provide four different "strengths" of control when
+subsequent matching fails. (*THEN) is the weakest, carrying on the match at the
+next alternative. (*PRUNE) comes next, failing the match at the current
+starting position, but allowing an advance to the next character (for an
+unanchored pattern). (*SKIP) is similar, except that the advance may be more
+than one character. (*COMMIT) is the strongest, causing the entire match to
+fail.
-If more than one is present in a pattern, the "stongest" one wins. For example,
-consider this pattern, where A, B, etc. are complex pattern fragments:
+If more than one such verb is present in a pattern, the "strongest" one wins.
+For example, consider this pattern, where A, B, etc. are complex pattern
+fragments:
(A(*COMMIT)B(*THEN)C|D)
Once A has matched, PCRE is committed to this match, at the current starting
position. If subsequently B matches, but C does not, the normal (*THEN) action
-of trying the next alternation (that is, D) does not happen because (*COMMIT)
+of trying the next alternative (that is, D) does not happen because (*COMMIT)
overrides.
SEE ALSO
Return to the PCRE index page.
diff -Nru pcre3-8.12/doc/html/pcreperform.html pcre3-8.31/doc/html/pcreperform.html
--- pcre3-8.12/doc/html/pcreperform.html 2011-01-15 17:27:46.000000000 +0000
+++ pcre3-8.31/doc/html/pcreperform.html 2012-07-06 09:55:28.000000000 +0000
@@ -24,9 +24,9 @@
COMPILED PATTERN MEMORY USAGE
-Patterns are compiled by PCRE into a reasonably efficient byte code, so that
-most simple patterns do not use much memory. However, there is one case where
-the memory usage of a compiled pattern can be unexpectedly large. If a
+Patterns are compiled by PCRE into a reasonably efficient interpretive code, so
+that most simple patterns do not use much memory. However, there is one case
+where the memory usage of a compiled pattern can be unexpectedly large. If a
parenthesized subpattern has a quantifier with a minimum greater than 1 and/or
a limited maximum, the whole subpattern is repeated in the compiled code. For
example, the pattern
@@ -48,12 +48,12 @@
((ab){1,1000}c){1,3}
-uses 51K bytes when compiled. When PCRE is compiled with its default internal
-pointer size of two bytes, the size limit on a compiled pattern is 64K, and
-this is reached with the above pattern if the outer repetition is increased
-from 3 to 4. PCRE can be compiled to use larger internal pointers and thus
-handle larger compiled patterns, but it is better to try to rewrite your
-pattern to use less memory if you can.
+uses 51K bytes when compiled using the 8-bit library. When PCRE is compiled
+with its default internal pointer size of two bytes, the size limit on a
+compiled pattern is 64K data units, and this is reached with the above pattern
+if the outer repetition is increased from 3 to 4. PCRE can be compiled to use
+larger internal pointers and thus handle larger compiled patterns, but it is
+better to try to rewrite your pattern to use less memory if you can.
One way of reducing the memory usage for such patterns is to make use of PCRE's
@@ -77,11 +77,11 @@
STACK USAGE AT RUN TIME
-When pcre_exec() is used for matching, certain kinds of pattern can cause
-it to use large amounts of the process stack. In some environments the default
-process stack is quite small, and if it runs out the result is often SIGSEGV.
-This issue is probably the most frequently raised problem with PCRE. Rewriting
-your pattern can often help. The
+When pcre_exec() or pcre16_exec() is used for matching, certain
+kinds of pattern can cause it to use large amounts of the process stack. In
+some environments the default process stack is quite small, and if it runs out
+the result is often SIGSEGV. This issue is probably the most frequently raised
+problem with PCRE. Rewriting your pattern can often help. The
pcrestack
documentation discusses this issue in detail.
@@ -110,8 +110,9 @@
backwards compatibility, and partly for performance reasons. However, you can
set PCRE_UCP if you want Unicode character properties to be used. This can
double the matching time for items such as \d, when matched with
-pcre_exec(); the performance loss is less with pcre_dfa_exec(), and
-in both cases there is not much difference for \b.
+a traditional matching function; the performance loss is less with
+a DFA matching function, and in both cases there is not much difference for
+\b.
When a pattern begins with .* not in parentheses, or in parentheses that are
@@ -186,9 +187,9 @@
REVISION
-This set of functions provides a POSIX-style API to the PCRE regular expression
-package. See the
+This set of functions provides a POSIX-style API for the PCRE regular
+expression 8-bit library. See the
pcreapi
documentation for a description of PCRE's native API, which contains much
-additional functionality.
+additional functionality. There is no POSIX-style wrapper for PCRE's 16-bit
+library.
The functions described here are just wrapper functions that ultimately call
@@ -282,9 +283,9 @@
Return to the PCRE index page.
diff -Nru pcre3-8.12/doc/html/pcreprecompile.html pcre3-8.31/doc/html/pcreprecompile.html
--- pcre3-8.12/doc/html/pcreprecompile.html 2011-01-15 17:27:46.000000000 +0000
+++ pcre3-8.31/doc/html/pcreprecompile.html 2012-07-06 09:55:28.000000000 +0000
@@ -28,24 +28,31 @@
If you are not using any private character tables (see the
pcre_maketables()
documentation), this is relatively straightforward. If you are using private
-tables, it is a little bit more complicated.
+tables, it is a little bit more complicated. However, if you are using the
+just-in-time optimization feature, it is not possible to save and reload the
+JIT data.
If you save compiled patterns to a file, you can copy them to a different host
-and run them there. This works even if the new host has the opposite endianness
-to the one on which the patterns were compiled. There may be a small
-performance penalty, but it should be insignificant. However, compiling regular
-expressions with one version of PCRE for use with a different version is not
-guaranteed to work and may cause crashes.
+and run them there. If the two hosts have different endianness (byte order),
+you should run the pcre[16]_pattern_to_host_byte_order() function on the
+new host before trying to match the pattern. The matching functions return
+PCRE_ERROR_BADENDIANNESS if they detect a pattern with the wrong endianness.
+
+
+Compiling regular expressions with one version of PCRE for use with a different
+version is not guaranteed to work and may cause crashes, and saving and
+restoring a compiled pattern loses any JIT optimization data.
-The value returned by pcre_compile() points to a single block of memory
-that holds the compiled pattern and associated data. You can find the length of
-this block in bytes by calling pcre_fullinfo() with an argument of
-PCRE_INFO_SIZE. You can then save the data in any appropriate manner. Here is
-sample code that compiles a pattern and writes it to a file. It assumes that
-the variable fd refers to a file that is open for output:
+The value returned by pcre[16]_compile() points to a single block of
+memory that holds the compiled pattern and associated data. You can find the
+length of this block in bytes by calling pcre[16]_fullinfo() with an
+argument of PCRE_INFO_SIZE. You can then save the data in any appropriate
+manner. Here is sample code for the 8-bit library that compiles a pattern and
+writes it to a file. It assumes that the variable fd refers to a file
+that is open for output:
-If the pattern has been studied, it is also possible to save the study data in
-a similar way to the compiled pattern itself. When studying generates
-additional information, pcre_study() returns a pointer to a
-pcre_extra data block. Its format is defined in the
+If the pattern has been studied, it is also possible to save the normal study
+data in a similar way to the compiled pattern itself. However, if the
+PCRE_STUDY_JIT_COMPILE was used, the just-in-time data that is created cannot
+be saved because it is too dependent on the current environment. When studying
+generates additional information, pcre[16]_study() returns a pointer to a
+pcre[16]_extra data block. Its format is defined in the
section on matching a pattern
in the
pcreapi
documentation. The study_data field points to the binary study data, and
-this is what you must save (not the pcre_extra block itself). The length
-of the study data can be obtained by calling pcre_fullinfo() with an
-argument of PCRE_INFO_STUDYSIZE. Remember to check that pcre_study() did
-return a non-NULL value before trying to save the study data.
+this is what you must save (not the pcre[16]_extra block itself). The
+length of the study data can be obtained by calling pcre[16]_fullinfo()
+with an argument of PCRE_INFO_STUDYSIZE. Remember to check that
+pcre[16]_study() did return a non-NULL value before trying to save the
+study data.
Re-using a precompiled pattern is straightforward. Having reloaded it into main
-memory, you pass its pointer to pcre_exec() or pcre_dfa_exec() in
-the usual way. This should work even on another host, and even if that host has
-the opposite endianness to the one where the pattern was compiled.
+memory, called pcre[16]_pattern_to_host_byte_order() if necessary,
+you pass its pointer to pcre[16]_exec() or pcre[16]_dfa_exec() in
+the usual way.
However, if you passed a pointer to custom character tables when the pattern
-was compiled (the tableptr argument of pcre_compile()), you must
-now pass a similar pointer to pcre_exec() or pcre_dfa_exec(),
-because the value saved with the compiled pattern will obviously be nonsense. A
-field in a pcre_extra() block is used to pass this data, as described in
-the
+was compiled (the tableptr argument of pcre[16]_compile()), you
+must now pass a similar pointer to pcre[16]_exec() or
+pcre[16]_dfa_exec(), because the value saved with the compiled pattern
+will obviously be nonsense. A field in a pcre[16]_extra() block is used
+to pass this data, as described in the
section on matching a pattern
in the
pcreapi
@@ -110,17 +120,18 @@
If you did not provide custom character tables when the pattern was compiled,
-the pointer in the compiled pattern is NULL, which causes pcre_exec() to
-use PCRE's internal tables. Thus, you do not need to take any special action at
-run time in this case.
+the pointer in the compiled pattern is NULL, which causes the matching
+functions to use PCRE's internal tables. Thus, you do not need to take any
+special action at run time in this case.
If you saved study data with the compiled pattern, you need to create your own
-pcre_extra data block and set the study_data field to point to the
+pcre[16]_extra data block and set the study_data field to point to the
reloaded study data. You must also set the PCRE_EXTRA_STUDY_DATA bit in the
flags field to indicate that study data is present. Then pass the
-pcre_extra block to pcre_exec() or pcre_dfa_exec() in the
-usual way.
+pcre[16]_extra block to the matching function in the usual way. If the
+pattern was studied for just-in-time optimization, that data cannot be saved,
+and so is lost by a save/restore cycle.
Return to the PCRE index page.
diff -Nru pcre3-8.12/doc/html/pcresample.html pcre3-8.31/doc/html/pcresample.html
--- pcre3-8.12/doc/html/pcresample.html 2011-01-15 17:27:46.000000000 +0000
+++ pcre3-8.31/doc/html/pcresample.html 2012-07-06 09:55:28.000000000 +0000
@@ -24,11 +24,12 @@
this listing to re-create pcredemo.c.
-The program compiles the regular expression that is its first argument, and
-matches it against the subject string in its second argument. No PCRE options
-are set, and default character tables are used. If matching succeeds, the
-program outputs the portion of the subject that matched, together with the
-contents of any captured substrings.
+The demonstration program, which uses the original PCRE 8-bit library, compiles
+the regular expression that is its first argument, and matches it against the
+subject string in its second argument. No PCRE options are set, and default
+character tables are used. If matching succeeds, the program outputs the
+portion of the subject that matched, together with the contents of any captured
+substrings.
If the -g option is given on the command line, the program then goes on to
@@ -65,8 +66,8 @@
Note that there is a much more comprehensive test program, called
pcretest,
-which supports many more facilities for testing regular expressions and the
-PCRE library. The
+which supports many more facilities for testing regular expressions and both
+PCRE libraries. The
pcredemo
program is provided as a simple coding example.
@@ -100,9 +101,9 @@
REVISION
Return to the PCRE index page.
diff -Nru pcre3-8.12/doc/html/pcrestack.html pcre3-8.31/doc/html/pcrestack.html
--- pcre3-8.12/doc/html/pcrestack.html 2011-01-15 17:27:46.000000000 +0000
+++ pcre3-8.31/doc/html/pcrestack.html 2012-07-06 09:55:28.000000000 +0000
@@ -16,11 +16,14 @@
PCRE DISCUSSION OF STACK USAGE
-When you call pcre_exec(), it makes use of an internal function called
-match(). This calls itself recursively at branch points in the pattern,
-in order to remember the state of the match so that it can back up and try a
-different alternative if the first one fails. As matching proceeds deeper and
-deeper into the tree of possibilities, the recursion depth increases.
+When you call pcre[16]_exec(), it makes use of an internal function
+called match(). This calls itself recursively at branch points in the
+pattern, in order to remember the state of the match so that it can back up and
+try a different alternative if the first one fails. As matching proceeds deeper
+and deeper into the tree of possibilities, the recursion depth increases. The
+match() function is also called in other circumstances, for example,
+whenever a parenthesized sub-pattern is entered, and in certain cases of
+repetition.
Not all calls of match() increase the recursion depth; for an item such
@@ -30,22 +33,32 @@
current call (a "tail recursion"), the function is just restarted instead.
-The pcre_dfa_exec() function operates in an entirely different way, and
-uses recursion only when there is a regular expression recursion or subroutine
-call in the pattern. This includes the processing of assertion and "once-only"
-subpatterns, which are handled like subroutine calls. Normally, these are never
-very deep, and the limit on the complexity of pcre_dfa_exec() is
-controlled by the amount of workspace it is given. However, it is possible to
-write patterns with runaway infinite recursions; such patterns will cause
-pcre_dfa_exec() to run out of stack. At present, there is no protection
-against this.
+The above comments apply when pcre[16]_exec() is run in its normal
+interpretive manner. If the pattern was studied with the
+PCRE_STUDY_JIT_COMPILE option, and just-in-time compiling was successful, and
+the options passed to pcre[16]_exec() were not incompatible, the matching
+process uses the JIT-compiled code instead of the match() function. In
+this case, the memory requirements are handled entirely differently. See the
+pcrejit
+documentation for details.
+
+
+The pcre[16]_dfa_exec() function operates in an entirely different way,
+and uses recursion only when there is a regular expression recursion or
+subroutine call in the pattern. This includes the processing of assertion and
+"once-only" subpatterns, which are handled like subroutine calls. Normally,
+these are never very deep, and the limit on the complexity of
+pcre[16]_dfa_exec() is controlled by the amount of workspace it is given.
+However, it is possible to write patterns with runaway infinite recursions;
+such patterns will cause pcre[16]_dfa_exec() to run out of stack. At
+present, there is no protection against this.
-The comments that follow do NOT apply to pcre_dfa_exec(); they are
-relevant only for pcre_exec().
+The comments that follow do NOT apply to pcre[16]_dfa_exec(); they are
+relevant only for pcre[16]_exec() without the JIT optimization.
Each time that match() is actually called recursively, it uses memory
@@ -81,54 +94,81 @@
than one character whenever possible.
-Compiling PCRE to use heap instead of stack for pcre_exec()
+Compiling PCRE to use heap instead of stack for pcre[16]_exec()
In environments where stack memory is constrained, you might want to compile
PCRE to use heap memory instead of stack for remembering back-up points when
-pcre_exec() is running. This makes it run a lot more slowly, however.
+pcre[16]_exec() is running. This makes it run a lot more slowly, however.
Details of how to do this are given in the
pcrebuild
documentation. When built in this way, instead of using the stack, PCRE obtains
and frees memory by calling the functions that are pointed to by the
-pcre_stack_malloc and pcre_stack_free variables. By default, these
-point to malloc() and free(), but you can replace the pointers to
-cause PCRE to use your own functions. Since the block sizes are always the
-same, and are always freed in reverse order, it may be possible to implement
-customized memory handlers that are more efficient than the standard functions.
+pcre[16]_stack_malloc and pcre[16]_stack_free variables. By
+default, these point to malloc() and free(), but you can replace
+the pointers to cause PCRE to use your own functions. Since the block sizes are
+always the same, and are always freed in reverse order, it may be possible to
+implement customized memory handlers that are more efficient than the standard
+functions.
You can set limits on the number of times that match() is called, both in
-total and recursively. If a limit is exceeded, pcre_exec() returns an
+total and recursively. If a limit is exceeded, pcre[16]_exec() returns an
error code. Setting suitable limits should prevent it from running out of
stack. The default values of the limits are very large, and unlikely ever to
operate. They can be changed when PCRE is built, and they can also be set when
-pcre_exec() is called. For details of these interfaces, see the
+pcre[16]_exec() is called. For details of these interfaces, see the
pcrebuild
documentation and the
-section on extra data for pcre_exec()
+section on extra data for pcre[16]_exec()
in the
pcreapi
documentation.
As a very rough rule of thumb, you should reckon on about 500 bytes per
-recursion. Thus, if you want to limit your stack usage to 8Mb, you
-should set the limit at 16000 recursions. A 64Mb stack, on the other hand, can
-support around 128000 recursions.
+recursion. Thus, if you want to limit your stack usage to 8Mb, you should set
+the limit at 16000 recursions. A 64Mb stack, on the other hand, can support
+around 128000 recursions.
In Unix-like environments, the pcretest test program has a command line
option (-S) that can be used to increase the size of its stack. As long
as the stack is large enough, another option (-M) can be used to find the
smallest limits that allow a particular pattern to match a given subject
-string. This is done by calling pcre_exec() repeatedly with different
+string. This is done by calling pcre[16]_exec() repeatedly with different
limits.
+Obtaining an estimate of stack usage
+
+
+The actual amount of stack used per recursion can vary quite a lot, depending
+on the compiler that was used to build PCRE and the optimization or debugging
+options that were set for it. The rule of thumb value of 500 bytes mentioned
+above may be larger or smaller than what is actually needed. A better
+approximation can be obtained by running this command:
+
+ pcretest -m -C
+
+The -C option causes pcretest to output information about the
+options with which PCRE was compiled. When -m is also given (before
+-C), information about stack use is given in a line like this:
+
+The value is approximate because some recursions need a bit more (up to perhaps
+16 more bytes).
+
+
+If the above command is given when PCRE is compiled to use the heap instead of
+the stack for recursion, the value that is output is the size of each block
+that is obtained from the heap.
+
+
Changing stack size in Unix-like systems
@@ -150,7 +190,7 @@
This reads the current limits (soft and hard) using getrlimit(), then
attempts to increase the soft limit to 100Mb using setrlimit(). You must
-do this before calling pcre_exec().
+do this before calling pcre[16]_exec().
Changing stack size in Mac OS X
@@ -176,9 +216,9 @@
REVISION
Return to the PCRE index page.
diff -Nru pcre3-8.12/doc/html/pcresyntax.html pcre3-8.31/doc/html/pcresyntax.html
--- pcre3-8.12/doc/html/pcresyntax.html 2011-01-15 17:27:46.000000000 +0000
+++ pcre3-8.31/doc/html/pcresyntax.html 2012-07-06 09:55:28.000000000 +0000
@@ -46,8 +46,7 @@
The full syntax and semantics of the regular expressions that are supported by
PCRE are described in the
pcrepattern
-documentation. This document contains just a quick-reference summary of the
-syntax.
+documentation. This document contains a quick-reference summary of the syntax.
@@ -62,7 +61,7 @@
\a alarm, that is, the BEL character (hex 07)
\cx "control-x", where x is any ASCII character
\e escape (hex 1B)
- \f formfeed (hex 0C)
+ \f form feed (hex 0C)
\n newline (hex 0A)
\r carriage return (hex 0D)
\t tab (hex 09)
@@ -76,25 +75,25 @@
. any character except newline;
in dotall mode, any character whatsoever
- \C one byte, even in UTF-8 mode (best avoided)
+ \C one data unit, even in UTF mode (best avoided)
\d a decimal digit
\D a character that is not a decimal digit
- \h a horizontal whitespace character
- \H a character that is not a horizontal whitespace character
+ \h a horizontal white space character
+ \H a character that is not a horizontal white space character
\N a character that is not a newline
\p{xx} a character with the xx property
\P{xx} a character without the xx property
\R a newline sequence
- \s a whitespace character
- \S a character that is not a whitespace character
- \v a vertical whitespace character
- \V a character that is not a vertical whitespace character
+ \s a white space character
+ \S a character that is not a white space character
+ \v a vertical white space character
+ \V a character that is not a vertical white space character
\w a "word" character
\W a "non-word" character
\X an extended Unicode sequence
In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII
-characters, even in UTF-8 mode. However, this can be changed by setting the
+characters, even in a UTF mode. However, this can be changed by setting the
PCRE_UCP option.
GENERAL CATEGORY PROPERTIES FOR \p and \P
@@ -162,13 +161,16 @@
Avestan,
Balinese,
Bamum,
+Batak,
Bengali,
Bopomofo,
+Brahmi,
Braille,
Buginese,
Buhid,
Canadian_Aboriginal,
Carian,
+Chakma,
Cham,
Cherokee,
Common,
@@ -211,7 +213,11 @@
Lycian,
Lydian,
Malayalam,
+Mandaic,
Meetei_Mayek,
+Meroitic_Cursive,
+Meroitic_Hieroglyphs,
+Miao,
Mongolian,
Myanmar,
New_Tai_Lue,
@@ -230,8 +236,10 @@
Runic,
Samaritan,
Saurashtra,
+Sharada,
Shavian,
Sinhala,
+Sora_Sompeng,
Sundanese,
Syloti_Nagri,
Syriac,
@@ -240,6 +248,7 @@
Tai_Le,
Tai_Tham,
Tai_Viet,
+Takri,
Tamil,
Telugu,
Thaana,
@@ -269,7 +278,7 @@
lower lower case letter
print printing, including space
punct printing, excluding alphanumeric
- space whitespace
+ space white space
upper upper case letter
word same as \w
xdigit hexadecimal digit
@@ -367,7 +376,8 @@
newline-setting options with similar syntax:
(*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
- (*UTF8) set UTF-8 mode (PCRE_UTF8)
+ (*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8)
+ (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16)
(*UCP) set PCRE_UCP (use Unicode properties for \d etc)
@@ -439,6 +449,7 @@
(*ACCEPT) force successful match
(*FAIL) force backtrack; synonym (*F)
+ (*MARK:NAME) set name to be passed back; synonym (*:NAME)
The following act only when a subsequent match failure causes a backtrack to
reach them. They all force a match failure, but they differ in what happens
@@ -447,14 +458,18 @@
(*COMMIT) overall failure, no advance of starting point
(*PRUNE) advance to next starting character
- (*SKIP) advance start to current matching position
+ (*PRUNE:NAME) equivalent to (*MARK:NAME)(*PRUNE)
+ (*SKIP) advance to current matching position
+ (*SKIP:NAME) advance to position corresponding to an earlier
+ (*MARK:NAME); if not found, the (*SKIP) is ignored
(*THEN) local failure, backtrack to next alternation
+ (*THEN:NAME) equivalent to (*MARK:NAME)(*THEN)
These are recognized only at the very start of the pattern or after a
-(*BSR_...) or (*UTF8) or (*UCP) option.
+(*BSR_...), (*UTF8), (*UTF16) or (*UCP) option.
(*CR) carriage return only
(*LF) linefeed only
@@ -466,7 +481,7 @@
WHAT \R MATCHES
These are recognized only at the very start of the pattern or after a
-(*...) option that sets the newline convention or UTF-8 or UCP mode.
+(*...) option that sets the newline convention or a UTF or UCP mode.
(*BSR_ANYCRLF) CR, LF, or CRLF
(*BSR_UNICODE) any Unicode newline sequence
@@ -495,9 +510,9 @@
REVISION
pcretest was written as a test program for the PCRE regular expression
@@ -42,30 +43,78 @@
documentation. For details of the PCRE library function calls and their
options, see the
pcreapi
-documentation.
+and
+pcre16
+documentation. The input for pcretest is a sequence of regular expression
+patterns and strings to be matched, as described below. The output shows the
+result of each match. Options on the command line and the patterns control PCRE
+options and exactly what is output.
+
+From release 8.30, two separate PCRE libraries can be built. The original one
+supports 8-bit character strings, whereas the newer 16-bit library supports
+character strings encoded in 16-bit units. The pcretest program can be
+used to test both libraries. However, it is itself still an 8-bit program,
+reading 8-bit input and writing 8-bit output. When testing the 16-bit library,
+the patterns and data strings are converted to 16-bit format before being
+passed to the PCRE library functions. Results are converted to 8-bit for
+output.
+
+
+References to functions and structures of the form pcre[16]_xx below
+mean "pcre_xx when using the 8-bit library or pcre16_xx when using
+the 16-bit library".
+
+-16
+If both the 8-bit and the 16-bit libraries have been built, this option causes
+the 16-bit library to be used. If only the 16-bit library has been built, this
+is the default (so has no effect). If only the 8-bit library has been built,
+this option causes an error.
-b
-Behave as if each regex has the /B (show bytecode) modifier; the internal
-form is output after compilation.
+Behave as if each pattern has the /B (show byte code) modifier; the
+internal form is output after compilation.
-C
Output the version number of the PCRE library, and all available information
-about the optional features that are included, and then exit.
+about the optional features that are included, and then exit. All other options
+are ignored.
+
+
+-Coption
+Output information about a specific build-time option, then exit. This
+functionality is intended for use in scripts such as RunTest. The
+following options output the value indicated:
+
+ linksize the internal link size (2, 3, or 4)
+ newline the default newline setting:
+ CR, LF, CRLF, ANYCRLF, or ANY
+
+The following options output 1 for true or zero for false:
+
+ jit just-in-time support is available
+ pcre16 the 16-bit library was built
+ pcre8 the 8-bit library was built
+ ucp Unicode property support is available
+ utf UTF-8 and/or UTF-16 support is available
+
-d
-Behave as if each regex has the /D (debug) modifier; the internal
+Behave as if each pattern has the /D (debug) modifier; the internal
form and information about the compiled pattern is output after compilation;
-d is equivalent to -b -i.
-dfa
Behave as if each data line contains the \D escape sequence; this causes the
-alternative matching function, pcre_dfa_exec(), to be used instead of the
-standard pcre_exec() function (more detail is given below).
+alternative matching function, pcre[16]_dfa_exec(), to be used instead of
+the standard pcre[16]_exec() function (more detail is given below).
-help
@@ -73,35 +122,35 @@
-i
-Behave as if each regex has the /I modifier; information about the
+Behave as if each pattern has the /I modifier; information about the
compiled pattern is given after compilation.
-M
Behave as if each data line contains the \M escape sequence; this causes
PCRE to discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings by
-calling pcre_exec() repeatedly with different limits.
+calling pcre[16]_exec() repeatedly with different limits.
-m
Output the size of each compiled pattern after it has been compiled. This is
-equivalent to adding /M to each regular expression. For compatibility
-with earlier versions of pcretest, -s is a synonym for -m.
+equivalent to adding /M to each regular expression. The size is given in
+bytes for both libraries.
-oosize
Set the number of elements in the output vector that is used when calling
-pcre_exec() or pcre_dfa_exec() to be osize. The default value
-is 45, which is enough for 14 capturing subexpressions for pcre_exec() or
-22 different matches for pcre_dfa_exec(). The vector size can be
-changed for individual matching calls by including \O in the data line (see
-below).
+pcre[16]_exec() or pcre[16]_dfa_exec() to be osize. The
+default value is 45, which is enough for 14 capturing subexpressions for
+pcre[16]_exec() or 22 different matches for pcre[16]_dfa_exec().
+The vector size can be changed for individual matching calls by including \O
+in the data line (see below).
-p
-Behave as if each regex has the /P modifier; the POSIX wrapper API is
+Behave as if each pattern has the /P modifier; the POSIX wrapper API is
used to call PCRE. None of the other options has any effect when -p is
-set.
+set. This option can be used only with the 8-bit library.
-q
@@ -109,10 +158,49 @@
-Ssize
-On Unix-like systems, set the size of the runtime stack to size
+On Unix-like systems, set the size of the run-time stack to size
megabytes.
+-s or -s+
+Behave as if each pattern has the /S modifier; in other words, force each
+pattern to be studied. If -s+ is used, all the JIT compile options are
+passed to pcre[16]_study(), causing just-in-time optimization to be set
+up if it is available, for both full and partial matching. Specific JIT compile
+options can be selected by following -s+ with a digit in the range 1 to
+7, which selects the JIT compile modes as follows:
+
+ 1 normal match only
+ 2 soft partial match only
+ 3 normal match and soft partial match
+ 4 hard partial match only
+ 6 soft and hard partial match
+ 7 all three modes (default)
+
+If -s++ is used instead of -s+ (with or without a following digit),
+the text "(JIT)" is added to the first output line after a match or no match
+when JIT-compiled code was actually used.
+
+
+If the /I or /D option is present on a pattern (requesting output
+about the compiled pattern), information about the result of studying is not
+included when studying is caused only by -s and neither -i nor
+-d is present on the command line. This behaviour means that the output
+from tests that are run with and without -s should be identical, except
+when options that output information about the actual running of a match are
+set.
+
+
+The -M, -t, and -tm options, which give information about
+resources used, are likely to produce different output with and without
+-s. Output may also differ if the /C option is present on an
+individual pattern. This uses callouts to trace the the matching process, and
+this may be different between studied and non-studied patterns. If the pattern
+contains (*MARK) items there may also be differences, for the same reason. The
+-s command line option can be overridden for specific patterns that
+should never be studied (see the /S pattern modifier below).
+
+
-t
Run each compile, study, and match many times with a timer, and output
resulting time per compile or match (in milliseconds). Do not set -m with
@@ -127,7 +215,7 @@
This is like -t except that it times only the matching phase, not the
compile or study phases.
If pcretest is given two filename arguments, it reads from the first and
writes to the second. If it is given only one filename argument, it reads from
@@ -184,19 +272,19 @@
is interpreted as the first line of a pattern that starts with "abc/", causing
pcretest to read the next line as a continuation of the regular expression.
A pattern may be followed by any number of modifiers, which are mostly single
characters. Following Perl usage, these are referred to below as, for example,
"the /i modifier", even though the delimiter of the pattern need not
-always be a slash, and no slash is used when writing modifiers. Whitespace may
+always be a slash, and no slash is used when writing modifiers. White space may
appear between the final pattern delimiter and the first modifier, and between
the modifiers themselves.
The /i, /m, /s, and /x modifiers set the PCRE_CASELESS,
PCRE_MULTILINE, PCRE_DOTALL, or PCRE_EXTENDED options, respectively, when
-pcre_compile() is called. These four modifier letters have the same
+pcre[16]_compile() is called. These four modifier letters have the same
effect as they do in Perl. For example:
/caseless/i
@@ -204,8 +292,12 @@
The following table shows additional modifiers for setting PCRE compile-time
options that do not correspond to anything in Perl:
- /8 PCRE_UTF8
- /? PCRE_NO_UTF8_CHECK
+ /8 PCRE_UTF8 ) when using the 8-bit
+ /? PCRE_NO_UTF8_CHECK ) library
+
+ /8 PCRE_UTF16 ) when using the 16-bit
+ /? PCRE_NO_UTF16_CHECK ) library
+
/A PCRE_ANCHORED
/C PCRE_AUTO_CALLOUT
/E PCRE_DOLLAR_ENDONLY
@@ -226,15 +318,18 @@
/<bsr_unicode> PCRE_BSR_UNICODE
The modifiers that are enclosed in angle brackets are literal strings as shown,
-including the angle brackets, but the letters can be in either case. This
-example sets multiline matching with CRLF as the line ending sequence:
+including the angle brackets, but the letters within can be in either case.
+This example sets multiline matching with CRLF as the line ending sequence:
- /^abc/m<crlf>
+ /^abc/m<CRLF>
-As well as turning on the PCRE_UTF8 option, the /8 modifier also causes
-any non-printing characters in output strings to be printed using the
-\x{hh...} notation if they are valid UTF-8 sequences. Full details of the PCRE
-options are given in the
+As well as turning on the PCRE_UTF8/16 option, the /8 modifier causes
+all non-printing characters in output strings to be printed using the
+\x{hh...} notation. Otherwise, those less than 0x100 are output in hex without
+the curly brackets.
+
+
+Full details of the PCRE options are given in the
pcreapi
documentation.
@@ -246,14 +341,14 @@
by the /g or /G modifier. After finding a match, PCRE is called
again to search the remainder of the subject string. The difference between
/g and /G is that the former uses the startoffset argument to
-pcre_exec() to start searching at a new point within the entire string
-(which is in effect what Perl does), whereas the latter passes over a shortened
-substring. This makes a difference to the matching process if the pattern
-begins with a lookbehind assertion (including \b or \B).
+pcre[16]_exec() to start searching at a new point within the entire
+string (which is in effect what Perl does), whereas the latter passes over a
+shortened substring. This makes a difference to the matching process if the
+pattern begins with a lookbehind assertion (including \b or \B).
-If any call to pcre_exec() in a /g or /G sequence matches an
-empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART and
+If any call to pcre[16]_exec() in a /g or /G sequence matches
+an empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART and
PCRE_ANCHORED flags set in order to search for another, non-empty, match at the
same point. If this second match fails, the start offset is advanced, and the
normal match is retried. This imitates the way Perl handles such cases when
@@ -271,17 +366,29 @@
The /+ modifier requests that as well as outputting the substring that
-matched the entire pattern, pcretest should in addition output the remainder of
-the subject string. This is useful for tests where the subject contains
-multiple copies of the same substring.
+matched the entire pattern, pcretest should in addition output the
+remainder of the subject string. This is useful for tests where the subject
+contains multiple copies of the same substring. If the + modifier appears
+twice, the same action is taken for captured substrings. In each case the
+remainder is output on the following line with a plus character following the
+capture number. Note that this modifier must not immediately follow the /S
+modifier because /S+ and /S++ have other meanings.
+
+
+The /= modifier requests that the values of all potential captured
+parentheses be output after a match. By default, only those up to the highest
+one actually used in the match are output (corresponding to the return code
+from pcre[16]_exec()). Values in the offsets vector corresponding to
+higher numbers should be set to -1, and these are output as "<unset>". This
+modifier gives a way of checking that this is happening.
The /B modifier is a debugging feature. It requests that pcretest
-output a representation of the compiled byte code after compilation. Normally
-this information contains length and offset values; however, if /Z is
-also present, this data is replaced by spaces. This is a special feature for
-use in the automatic test scripts; it ensures that the same output is generated
-for different internal link sizes.
+output a representation of the compiled code after compilation. Normally this
+information contains length and offset values; however, if /Z is also
+present, this data is replaced by spaces. This is a special feature for use in
+the automatic test scripts; it ensures that the same output is generated for
+different internal link sizes.
The /D modifier is a PCRE debugging feature, and is equivalent to
@@ -289,29 +396,29 @@
The /F modifier causes pcretest to flip the byte order of the
-fields in the compiled pattern that contain 2-byte and 4-byte numbers. This
-facility is for testing the feature in PCRE that allows it to execute patterns
-that were compiled on a host with a different endianness. This feature is not
-available when the POSIX interface to PCRE is being used, that is, when the
-/P pattern modifier is specified. See also the section about saving and
-reloading compiled patterns below.
+2-byte and 4-byte fields in the compiled pattern. This facility is for testing
+the feature in PCRE that allows it to execute patterns that were compiled on a
+host with a different endianness. This feature is not available when the POSIX
+interface to PCRE is being used, that is, when the /P pattern modifier is
+specified. See also the section about saving and reloading compiled patterns
+below.
The /I modifier requests that pcretest output information about the
compiled pattern (whether it is anchored, has a fixed first character, and
-so on). It does this by calling pcre_fullinfo() after compiling a
+so on). It does this by calling pcre[16]_fullinfo() after compiling a
pattern. If the pattern is studied, the results of that are also output.
The /K modifier requests pcretest to show names from backtracking
-control verbs that are returned from calls to pcre_exec(). It causes
-pcretest to create a pcre_extra block if one has not already been
-created by a call to pcre_study(), and to set the PCRE_EXTRA_MARK flag
-and the mark field within it, every time that pcre_exec() is
-called. If the variable that the mark field points to is non-NULL for a
-match, non-match, or partial match, pcretest prints the string to which
-it points. For a match, this is shown on a line by itself, tagged with "MK:".
-For a non-match it is added to the message.
+control verbs that are returned from calls to pcre[16]_exec(). It causes
+pcretest to create a pcre[16]_extra block if one has not already
+been created by a call to pcre[16]_study(), and to set the
+PCRE_EXTRA_MARK flag and the mark field within it, every time that
+pcre[16]_exec() is called. If the variable that the mark field
+points to is non-NULL for a match, non-match, or partial match, pcretest
+prints the string to which it points. For a match, this is shown on a line by
+itself, tagged with "MK:". For a non-match it is added to the message.
The /L modifier must be followed directly by the name of a locale, for
@@ -320,25 +427,62 @@
/pattern/Lfr_FR
For this reason, it must be the last modifier. The given locale is set,
-pcre_maketables() is called to build a set of character tables for the
-locale, and this is then passed to pcre_compile() when compiling the
-regular expression. Without an /L (or /T) modifier, NULL is passed
-as the tables pointer; that is, /L applies only to the expression on
-which it appears.
-
-
-The /M modifier causes the size of memory block used to hold the compiled
-pattern to be output.
-
-
-The /S modifier causes pcre_study() to be called after the
-expression has been compiled, and the results used when the expression is
-matched.
+pcre[16]_maketables() is called to build a set of character tables for
+the locale, and this is then passed to pcre[16]_compile() when compiling
+the regular expression. Without an /L (or /T) modifier, NULL is
+passed as the tables pointer; that is, /L applies only to the expression
+on which it appears.
+
+
+The /M modifier causes the size in bytes of the memory block used to hold
+the compiled pattern to be output. This does not include the size of the
+pcre[16] block; it is just the actual compiled data. If the pattern is
+successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the
+JIT compiled code is also output.
+
+
+If the /S modifier appears once, it causes pcre[16]_study() to be
+called after the expression has been compiled, and the results used when the
+expression is matched. If /S appears twice, it suppresses studying, even
+if it was requested externally by the -s command line option. This makes
+it possible to specify that certain patterns are always studied, and others are
+never studied, independently of -s. This feature is used in the test
+files in a few cases where the output is different when the pattern is studied.
+
+
+If the /S modifier is immediately followed by a + character, the call to
+pcre[16]_study() is made with all the JIT study options, requesting
+just-in-time optimization support if it is available, for both normal and
+partial matching. If you want to restrict the JIT compiling modes, you can
+follow /S+ with a digit in the range 1 to 7:
+
+ 1 normal match only
+ 2 soft partial match only
+ 3 normal match and soft partial match
+ 4 hard partial match only
+ 6 soft and hard partial match
+ 7 all three modes (default)
+
+If /S++ is used instead of /S+ (with or without a following digit),
+the text "(JIT)" is added to the first output line after a match or no match
+when JIT-compiled code was actually used.
+
+
+Note that there is also an independent /+ modifier; it must not be given
+immediately after /S or /S+ because this will be misinterpreted.
+
+
+If JIT studying is successful, the compiled JIT code will automatically be used
+when pcre[16]_exec() is run, except when incompatible run-time options
+are specified. For more details, see the
+pcrejit
+documentation. See also the \J escape sequence below for a way of
+setting the size of the JIT stack.
The /T modifier must be followed by a single digit. It causes a specific
-set of built-in character tables to be passed to pcre_compile(). It is
-used in the standard PCRE tests to check behaviour with different character
+set of built-in character tables to be passed to pcre[16]_compile(). It
+is used in the standard PCRE tests to check behaviour with different character
tables. The digit specifies the tables as follows:
0 the default ASCII tables, as distributed in
@@ -353,8 +497,9 @@
The /P modifier causes pcretest to call PCRE via the POSIX wrapper
-API rather than its native API. When /P is set, the following modifiers
-set options for the regcomp() function:
+API rather than its native API. This supports only the 8-bit library. When
+/P is set, the following modifiers set options for the regcomp()
+function:
/i REG_ICASE
/m REG_NEWLINE
@@ -367,11 +512,11 @@
The /+ modifier works as described above. All other modifiers are
ignored.
- DATA LINES
+ DATA LINES
-Before each data line is passed to pcre_exec(), leading and trailing
-whitespace is removed, and it is then scanned for \ escapes. Some of these are
-pretty esoteric features, intended for checking out some of the more
+Before each data line is passed to pcre[16]_exec(), leading and trailing
+white space is removed, and it is then scanned for \ escapes. Some of these
+are pretty esoteric features, intended for checking out some of the more
complicated features of PCRE. If you are just testing "ordinary" regular
expressions, you probably don't need any of these. The following escapes are
recognized:
@@ -379,58 +524,68 @@
\a alarm (BEL, \x07)
\b backspace (\x08)
\e escape (\x27)
- \f formfeed (\x0c)
+ \f form feed (\x0c)
\n newline (\x0a)
\qdd set the PCRE_MATCH_LIMIT limit to dd (any number of digits)
\r carriage return (\x0d)
\t tab (\x09)
\v vertical tab (\x0b)
- \nnn octal character (up to 3 octal digits)
- always a byte unless > 255 in UTF-8 mode
+ \nnn octal character (up to 3 octal digits); always
+ a byte unless > 255 in UTF-8 or 16-bit mode
\xhh hexadecimal byte (up to 2 hex digits)
- \x{hh...} hexadecimal character, any number of digits in UTF-8 mode
- \A pass the PCRE_ANCHORED option to pcre_exec() or pcre_dfa_exec()
- \B pass the PCRE_NOTBOL option to pcre_exec() or pcre_dfa_exec()
- \Cdd call pcre_copy_substring() for substring dd after a successful match (number less than 32)
- \Cname call pcre_copy_named_substring() for substring "name" after a successful match (name termin-
+ \x{hh...} hexadecimal character (any number of hex digits)
+ \A pass the PCRE_ANCHORED option to pcre[16]_exec() or pcre[16]_dfa_exec()
+ \B pass the PCRE_NOTBOL option to pcre[16]_exec() or pcre[16]_dfa_exec()
+ \Cdd call pcre[16]_copy_substring() for substring dd after a successful match (number less than 32)
+ \Cname call pcre[16]_copy_named_substring() for substring "name" after a successful match (name termin-
ated by next non alphanumeric character)
\C+ show the current captured substrings at callout time
\C- do not supply a callout function
\C!n return 1 instead of 0 when callout number n is reached
\C!n!m return 1 instead of 0 when callout number n is reached for the nth time
\C*n pass the number n (may be negative) as callout data; this is used as the callout return value
- \D use the pcre_dfa_exec() match function
- \F only shortest match for pcre_dfa_exec()
- \Gdd call pcre_get_substring() for substring dd after a successful match (number less than 32)
- \Gname call pcre_get_named_substring() for substring "name" after a successful match (name termin-
+ \D use the pcre[16]_dfa_exec() match function
+ \F only shortest match for pcre[16]_dfa_exec()
+ \Gdd call pcre[16]_get_substring() for substring dd after a successful match (number less than 32)
+ \Gname call pcre[16]_get_named_substring() for substring "name" after a successful match (name termin-
ated by next non-alphanumeric character)
- \L call pcre_get_substringlist() after a successful match
+ \Jdd set up a JIT stack of dd kilobytes maximum (any number of digits)
+ \L call pcre[16]_get_substringlist() after a successful match
\M discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings
- \N pass the PCRE_NOTEMPTY option to pcre_exec() or pcre_dfa_exec(); if used twice, pass the
+ \N pass the PCRE_NOTEMPTY option to pcre[16]_exec() or pcre[16]_dfa_exec(); if used twice, pass the
PCRE_NOTEMPTY_ATSTART option
- \Odd set the size of the output vector passed to pcre_exec() to dd (any number of digits)
- \P pass the PCRE_PARTIAL_SOFT option to pcre_exec() or pcre_dfa_exec(); if used twice, pass the
+ \Odd set the size of the output vector passed to pcre[16]_exec() to dd (any number of digits)
+ \P pass the PCRE_PARTIAL_SOFT option to pcre[16]_exec() or pcre[16]_dfa_exec(); if used twice, pass the
PCRE_PARTIAL_HARD option
\Qdd set the PCRE_MATCH_LIMIT_RECURSION limit to dd (any number of digits)
- \R pass the PCRE_DFA_RESTART option to pcre_dfa_exec()
+ \R pass the PCRE_DFA_RESTART option to pcre[16]_dfa_exec()
\S output details of memory get/free calls during matching
- \Y pass the PCRE_NO_START_OPTIMIZE option to pcre_exec() or pcre_dfa_exec()
- \Z pass the PCRE_NOTEOL option to pcre_exec() or pcre_dfa_exec()
- \? pass the PCRE_NO_UTF8_CHECK option to pcre_exec() or pcre_dfa_exec()
+ \Y pass the PCRE_NO_START_OPTIMIZE option to pcre[16]_exec() or pcre[16]_dfa_exec()
+ \Z pass the PCRE_NOTEOL option to pcre[16]_exec() or pcre[16]_dfa_exec()
+ \? pass the PCRE_NO_UTF[8|16]_CHECK option to pcre[16]_exec() or pcre[16]_dfa_exec()
\>dd start the match at offset dd (optional "-"; then any number of digits); this sets the startoffset
- argument for pcre_exec() or pcre_dfa_exec()
- \<cr> pass the PCRE_NEWLINE_CR option to pcre_exec() or pcre_dfa_exec()
- \<lf> pass the PCRE_NEWLINE_LF option to pcre_exec() or pcre_dfa_exec()
- \<crlf> pass the PCRE_NEWLINE_CRLF option to pcre_exec() or pcre_dfa_exec()
- \<anycrlf> pass the PCRE_NEWLINE_ANYCRLF option to pcre_exec() or pcre_dfa_exec()
- \<any> pass the PCRE_NEWLINE_ANY option to pcre_exec() or pcre_dfa_exec()
-
-Note that \xhh always specifies one byte, even in UTF-8 mode; this makes it
-possible to construct invalid UTF-8 sequences for testing purposes. On the
-other hand, \x{hh} is interpreted as a UTF-8 character in UTF-8 mode,
-generating more than one byte if the value is greater than 127. When not in
-UTF-8 mode, it generates one byte for values less than 256, and causes an error
-for greater values.
+ argument for pcre[16]_exec() or pcre[16]_dfa_exec()
+ \<cr> pass the PCRE_NEWLINE_CR option to pcre[16]_exec() or pcre[16]_dfa_exec()
+ \<lf> pass the PCRE_NEWLINE_LF option to pcre[16]_exec() or pcre[16]_dfa_exec()
+ \<crlf> pass the PCRE_NEWLINE_CRLF option to pcre[16]_exec() or pcre[16]_dfa_exec()
+ \<anycrlf> pass the PCRE_NEWLINE_ANYCRLF option to pcre[16]_exec() or pcre[16]_dfa_exec()
+ \<any> pass the PCRE_NEWLINE_ANY option to pcre[16]_exec() or pcre[16]_dfa_exec()
+
+The use of \x{hh...} is not dependent on the use of the /8 modifier on
+the pattern. It is recognized always. There may be any number of hexadecimal
+digits inside the braces; invalid values provoke error messages.
+
+
+Note that \xhh specifies one byte rather than one character in UTF-8 mode;
+this makes it possible to construct invalid UTF-8 sequences for testing
+purposes. On the other hand, \x{hh} is interpreted as a UTF-8 character in
+UTF-8 mode, generating more than one byte if the value is greater than 127.
+When testing the 8-bit library not in UTF-8 mode, \x{hh} generates one byte
+for values less than 256, and causes an error for greater values.
+
+
+In UTF-16 mode, all 4-digit \x{hhhh} values are accepted. This makes it
+possible to construct invalid UTF-16 sequences for testing purposes.
The escapes that specify line ending sequences are literal strings, exactly as
@@ -443,22 +598,33 @@
input.
-If \M is present, pcretest calls pcre_exec() several times, with
-different values in the match_limit and match_limit_recursion
-fields of the pcre_extra data structure, until it finds the minimum
-numbers for each parameter that allow pcre_exec() to complete. The
-match_limit number is a measure of the amount of backtracking that takes
-place, and checking it out can be instructive. For most simple matches, the
-number is quite small, but for patterns with very large numbers of matching
-possibilities, it can become large very quickly with increasing length of
-subject string. The match_limit_recursion number is a measure of how much
-stack (or, if PCRE is compiled with NO_RECURSE, how much heap) memory is needed
-to complete the match attempt.
+The \J escape provides a way of setting the maximum stack size that is
+used by the just-in-time optimization code. It is ignored if JIT optimization
+is not being used. Providing a stack that is larger than the default 32K is
+necessary only for very complicated patterns.
+
+
+If \M is present, pcretest calls pcre[16]_exec() several times,
+with different values in the match_limit and match_limit_recursion
+fields of the pcre[16]_extra data structure, until it finds the minimum
+numbers for each parameter that allow pcre[16]_exec() to complete without
+error. Because this is testing a specific feature of the normal interpretive
+pcre[16]_exec() execution, the use of any JIT optimization that might
+have been set up by the /S+ qualifier of -s+ option is disabled.
+
+
+The match_limit number is a measure of the amount of backtracking
+that takes place, and checking it out can be instructive. For most simple
+matches, the number is quite small, but for patterns with very large numbers of
+matching possibilities, it can become large very quickly with increasing length
+of subject string. The match_limit_recursion number is a measure of how
+much stack (or, if PCRE is compiled with NO_RECURSE, how much heap) memory is
+needed to complete the match attempt.
When \O is used, the value specified may be higher or lower than the size set
by the -O command line option (or defaulted to 45); \O applies only to
-the call of pcre_exec() for the line in which it appears.
+the call of pcre[16]_exec() for the line in which it appears.
If the /P modifier was present on the pattern, causing the POSIX wrapper
@@ -466,20 +632,11 @@
\N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and REG_NOTEOL, respectively,
to be passed to regexec().
-
-The use of \x{hh...} to represent UTF-8 characters is not dependent on the use
-of the /8 modifier on the pattern. It is recognized always. There may be
-any number of hexadecimal digits inside the braces. The result is from one to
-six bytes, encoded according to the original UTF-8 rules of RFC 2279. This
-allows for values in the range 0 to 0x7FFFFFFF. Note that not all of those are
-valid Unicode code points, or indeed valid UTF-8 characters according to the
-later rules in RFC 3629.
-
By default, pcretest uses the standard PCRE matching function,
-pcre_exec() to match each data line. From release 6.0, PCRE supports an
-alternative matching function, pcre_dfa_test(), which operates in a
+pcre[16]_exec() to match each data line. PCRE also supports an
+alternative matching function, pcre[16]_dfa_test(), which operates in a
different way, and has some restrictions. The differences between the two
functions are described in the
pcrematching
@@ -487,29 +644,32 @@
If a data line contains the \D escape sequence, or if the command line
-contains the -dfa option, the alternative matching function is called.
+contains the -dfa option, the alternative matching function is used.
This function finds all possible matches at a given point. If, however, the \F
escape sequence is present in the data line, it stops after the first match is
found. This is always the shortest possible match.
This section describes the output when the normal matching function,
-pcre_exec(), is being used.
+pcre[16]_exec(), is being used.
-When a match succeeds, pcretest outputs the list of captured substrings that
-pcre_exec() returns, starting with number 0 for the string that matched
-the whole pattern. Otherwise, it outputs "No match" when the return is
+When a match succeeds, pcretest outputs the list of captured substrings
+that pcre[16]_exec() returns, starting with number 0 for the string that
+matched the whole pattern. Otherwise, it outputs "No match" when the return is
PCRE_ERROR_NOMATCH, and "Partial match:" followed by the partially matching
-substring when pcre_exec() returns PCRE_ERROR_PARTIAL. (Note that this is
-the entire substring that was inspected during the partial match; it may
-include characters before the actual match start if a lookbehind assertion,
-\K, \b, or \B was involved.) For any other returns, it outputs the PCRE
-negative error number. Here is an example of an interactive pcretest run.
+substring when pcre[16]_exec() returns PCRE_ERROR_PARTIAL. (Note that
+this is the entire substring that was inspected during the partial match; it
+may include characters before the actual match start if a lookbehind assertion,
+\K, \b, or \B was involved.) For any other return, pcretest outputs
+the PCRE negative error number and a short descriptive phrase. If the error is
+a failed UTF string check, the offset of the start of the failing character and
+the reason code are also output, provided that the size of the output vector is
+at least two. Here is an example of an interactive pcretest run.
$ pcretest
- PCRE version 7.0 30-Nov-2006
+ PCRE version 8.13 2011-04-30
re> /^abc(\d+)/
data> abc123
@@ -518,11 +678,11 @@
data> xyz
No match
-Note that unset capturing substrings that are not followed by one that is set
-are not returned by pcre_exec(), and are not shown by pcretest. In
-the following example, there are two capturing substrings, but when the first
-data line is matched, the second, unset substring is not shown. An "internal"
-unset substring is shown as "<unset>", as for the second data line.
+Unset capturing substrings that are not followed by one that is set are not
+returned by pcre[16]_exec(), and are not shown by pcretest. In the
+following example, there are two capturing substrings, but when the first data
+line is matched, the second, unset substring is not shown. An "internal" unset
+substring is shown as "<unset>", as for the second data line.
re> /(a)|(b)/
data> a
@@ -533,11 +693,12 @@
1: <unset>
2: b
-If the strings contain any non-printing characters, they are output as \0x
-escapes, or as \x{...} escapes if the /8 modifier was present on the
-pattern. See below for the definition of non-printing characters. If the
-pattern has the /+ modifier, the output for substring 0 is followed by
-the the rest of the subject string, identified by "0+" like this:
+If the strings contain any non-printing characters, they are output as \xhh
+escapes if the value is less than 256 and UTF mode is not set. Otherwise they
+are output as \x{hh...} escapes. See below for the definition of non-printing
+characters. If the pattern has the /+ modifier, the output for substring
+0 is followed by the the rest of the subject string, identified by "0+" like
+this:
-"No match" is output only if the first match attempt fails.
+"No match" is output only if the first match attempt fails. Here is an example
+of a failure message (the offset 4 that is specified by \>4 is past the end of
+the subject string):
+
If any of the sequences \C, \G, or \L are present in a
@@ -572,9 +740,9 @@
included in data by means of the \n escape (or \r, \r\n, etc., depending on
the newline sequence setting).
-When the alternative matching function, pcre_dfa_exec(), is used (by
+When the alternative matching function, pcre[16]_dfa_exec(), is used (by
means of the \D escape sequence or the -dfa command line option), the
output consists of a list of all the matches that start at the first point in
the subject where there is at least one match. For example:
@@ -608,7 +776,7 @@
Since the matching function does not support substring capture, the escape
sequences that are concerned with captured substrings are not relevant.
When the alternative matching function has given the PCRE_ERROR_PARTIAL return,
indicating that the subject partially matched the pattern, you can restart the
@@ -625,21 +793,21 @@
pcrepartial
documentation.
If the pattern contains any callout requests, pcretest's callout function
is called during matching. This works with both matching functions. By default,
the called function displays the callout number, the start and current
positions in the text at the callout time, and the next pattern item to be
-tested. For example, the output
+tested. For example:
--->pqrabcdef
0 ^ ^ \d
-indicates that callout number 0 occurred for a match attempt starting at the
-fourth character of the subject string, when the pointer was at the seventh
-character of the data, and when the next pattern item was \d. Just one
-circumflex is output if the start and current positions are the same.
+This output indicates that callout number 0 occurred for a match attempt
+starting at the fourth character of the subject string, when the pointer was at
+the seventh character of the data, and when the next pattern item was \d. Just
+one circumflex is output if the start and current positions are the same.
Callouts numbered 255 are assumed to be automatic callouts, inserted as a
@@ -656,9 +824,28 @@
+10 ^ ^
0: E*
+If a pattern contains (*MARK) items, an additional line is output whenever
+a change of latest mark is passed to the callout function. For example:
+
+ re> /a(*MARK:X)bc/C
+ data> abc
+ --->abc
+ +0 ^ a
+ +1 ^^ (*MARK:X)
+ +10 ^^ b
+ Latest Mark: X
+ +11 ^ ^ c
+ +12 ^ ^
+ 0: abc
+
+The mark changes between matching "a" and "b", but stays the same for the rest
+of the match, so nothing more is output. If, as a result of backtracking, the
+mark reverts to being unset, the text "<unset>" is output.
+
+
The callout function in pcretest returns zero (carry on matching) by
default, but you can use a \C item in a data line (as described above) to
-change this.
+change this and other parameters of the callout.
Inserting callouts can be helpful when using pcretest to check
@@ -667,7 +854,7 @@
pcrecallout
documentation.
When pcretest is outputting text in the compiled version of a pattern,
bytes other than 32-126 are always treated as non-printing characters are are
@@ -679,10 +866,10 @@
the pattern (using the /L modifier). In this case, the isprint()
function to distinguish printing and non-printing characters.
The facilities described in this section are not available when the POSIX
-inteface to PCRE is being used, that is, when the /P pattern modifier is
+interface to PCRE is being used, that is, when the /P pattern modifier is
specified.
@@ -695,6 +882,8 @@
See the
pcreprecompile
documentation for a discussion about saving and re-using compiled patterns.
+Note that if the pattern was successfully studied with JIT optimization, the
+JIT data cannot be saved.
The data that is written is binary. The first eight bytes are the length of the
@@ -703,28 +892,37 @@
there is no study data (either the pattern was not studied, or studying did not
return any data), the second length is zero. The lengths are followed by an
exact copy of the compiled pattern. If there is additional study data, this
-follows immediately after the compiled pattern. After writing the file,
-pcretest expects to read a new pattern.
+(excluding any JIT data) follows immediately after the compiled pattern. After
+writing the file, pcretest expects to read a new pattern.
-A saved pattern can be reloaded into pcretest by specifing < and a file
+A saved pattern can be reloaded into pcretest by specifying < and a file
name instead of a pattern. The name of the file must not contain a < character,
as otherwise pcretest will interpret the line as a pattern delimited by <
characters.
For example:
re> </some/file
- Compiled regex loaded from /some/file
+ Compiled pattern loaded from /some/file
No study data
-When the pattern has been loaded, pcretest proceeds to read data lines in
-the usual way.
+If the pattern was previously studied with the JIT optimization, the JIT
+information cannot be saved and restored, and so is lost. When the pattern has
+been loaded, pcretest proceeds to read data lines in the usual way.
You can copy a file written by pcretest to a different host and reload it
there, even if the new host has opposite endianness to the one on which the
pattern was compiled. For example, you can compile on an i86 machine and run on
-a SPARC machine.
+a SPARC machine. When a pattern is reloaded on a host with different
+endianness, the confirmation message is changed to:
+
+ Compiled pattern (byte-inverted) loaded from /some/file
+
+The test suite contains some saved pre-compiled patterns with different
+endianness. These are reloaded using "<!" instead of just "<". This suppresses
+the "(byte-inverted)" text so that the output is the same on all hosts. It also
+forces debugging output once the pattern has been reloaded.
File names for saving and reloading can be absolute or relative, but note that
@@ -741,12 +939,13 @@
Finally, if you attempt to load a file that is not in the correct format, the
result is undefined.
+This page is part of the PCRE HTML documentation. It was generated automatically
+from the original man page. If there is any nonsense in it, please consult the
+man page, in case the conversion went wrong.
+
+
+UTF-8, UTF-16, AND UNICODE PROPERTY SUPPORT
+
+
+From Release 8.30, in addition to its previous UTF-8 support, PCRE also
+supports UTF-16 by means of a separate 16-bit library. This can be built as
+well as, or instead of, the 8-bit library.
+
+
+UTF-8 SUPPORT
+
+
+In order process UTF-8 strings, you must build PCRE's 8-bit library with UTF
+support, and, in addition, you must call
+pcre_compile()
+with the PCRE_UTF8 option flag, or the pattern must start with the sequence
+(*UTF8). When either of these is the case, both the pattern and any subject
+strings that are matched against it are treated as UTF-8 strings instead of
+strings of 1-byte characters.
+
+
+UTF-16 SUPPORT
+
+
+In order process UTF-16 strings, you must build PCRE's 16-bit library with UTF
+support, and, in addition, you must call
+pcre16_compile()
+with the PCRE_UTF16 option flag, or the pattern must start with the sequence
+(*UTF16). When either of these is the case, both the pattern and any subject
+strings that are matched against it are treated as UTF-16 strings instead of
+strings of 16-bit characters.
+
+
+UTF SUPPORT OVERHEAD
+
+
+If you compile PCRE with UTF support, but do not use it at run time, the
+library will be a bit bigger, but the additional run time overhead is limited
+to testing the PCRE_UTF8/16 flag occasionally, so should not be very big.
+
+
+UNICODE PROPERTY SUPPORT
+
+
+If PCRE is built with Unicode character property support (which implies UTF
+support), the escape sequences \p{..}, \P{..}, and \X can be used.
+The available properties that can be tested are limited to the general
+category properties such as Lu for an upper case letter or Nd for a decimal
+number, the Unicode script names such as Arabic or Han, and the derived
+properties Any and L&. A full list is given in the
+pcrepattern
+documentation. Only the short names for properties are supported. For example,
+\p{L} matches a letter. Its Perl synonym, \p{Letter}, is not supported.
+Furthermore, in Perl, many properties may optionally be prefixed by "Is", for
+compatibility with Perl 5.6. PCRE does not support this.
+
+
+Validity of UTF-8 strings
+
+
+When you set the PCRE_UTF8 flag, the byte strings passed as patterns and
+subjects are (by default) checked for validity on entry to the relevant
+functions. The entire string is checked before any other processing takes
+place. From release 7.3 of PCRE, the check is according the rules of RFC 3629,
+which are themselves derived from the Unicode specification. Earlier releases
+of PCRE followed the rules of RFC 2279, which allows the full range of 31-bit
+values (0 to 0x7FFFFFFF). The current check allows only values in the range U+0
+to U+10FFFF, excluding U+D800 to U+DFFF.
+
+
+The excluded code points are the "Surrogate Area" of Unicode. They are reserved
+for use by UTF-16, where they are used in pairs to encode codepoints with
+values greater than 0xFFFF. The code points that are encoded by UTF-16 pairs
+are available independently in the UTF-8 encoding. (In other words, the whole
+surrogate thing is a fudge for UTF-16 which unfortunately messes up UTF-8.)
+
+
+If an invalid UTF-8 string is passed to PCRE, an error return is given. At
+compile time, the only additional information is the offset to the first byte
+of the failing character. The run-time functions pcre_exec() and
+pcre_dfa_exec() also pass back this information, as well as a more
+detailed reason code if the caller has provided memory in which to do this.
+
+
+In some situations, you may already know that your strings are valid, and
+therefore want to skip these checks in order to improve performance, for
+example in the case of a long subject string that is being scanned repeatedly
+with different patterns. If you set the PCRE_NO_UTF8_CHECK flag at compile time
+or at run time, PCRE assumes that the pattern or subject it is given
+(respectively) contains only valid UTF-8 codes. In this case, it does not
+diagnose an invalid UTF-8 string.
+
+
+If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, what
+happens depends on why the string is invalid. If the string conforms to the
+"old" definition of UTF-8 (RFC 2279), it is processed as a string of characters
+in the range 0 to 0x7FFFFFFF by pcre_dfa_exec() and the interpreted
+version of pcre_exec(). In other words, apart from the initial validity
+test, these functions (when in UTF-8 mode) handle strings according to the more
+liberal rules of RFC 2279. However, the just-in-time (JIT) optimization for
+pcre_exec() supports only RFC 3629. If you are using JIT optimization, or
+if the string does not even conform to RFC 2279, the result is undefined. Your
+program may crash.
+
+
+If you want to process strings of values in the full range 0 to 0x7FFFFFFF,
+encoded in a UTF-8-like manner as per the old RFC, you can set
+PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in this
+situation, you will have to apply your own validity check, and avoid the use of
+JIT optimization.
+
+
+Validity of UTF-16 strings
+
+
+When you set the PCRE_UTF16 flag, the strings of 16-bit data units that are
+passed as patterns and subjects are (by default) checked for validity on entry
+to the relevant functions. Values other than those in the surrogate range
+U+D800 to U+DFFF are independent code points. Values in the surrogate range
+must be used in pairs in the correct manner.
+
+
+If an invalid UTF-16 string is passed to PCRE, an error return is given. At
+compile time, the only additional information is the offset to the first data
+unit of the failing character. The run-time functions pcre16_exec() and
+pcre16_dfa_exec() also pass back this information, as well as a more
+detailed reason code if the caller has provided memory in which to do this.
+
+
+In some situations, you may already know that your strings are valid, and
+therefore want to skip these checks in order to improve performance. If you set
+the PCRE_NO_UTF16_CHECK flag at compile time or at run time, PCRE assumes that
+the pattern or subject it is given (respectively) contains only valid UTF-16
+sequences. In this case, it does not diagnose an invalid UTF-16 string.
+
+
+General comments about UTF modes
+
+
+1. Codepoints less than 256 can be specified by either braced or unbraced
+hexadecimal escape sequences (for example, \x{b3} or \xb3). Larger values
+have to use braced sequences.
+
+
+2. Octal numbers up to \777 are recognized, and in UTF-8 mode, they match
+two-byte characters for values greater than \177.
+
+
+3. Repeat quantifiers apply to complete UTF characters, not to individual
+data units, for example: \x{100}{3}.
+
+
+4. The dot metacharacter matches one UTF character instead of a single data
+unit.
+
+
+5. The escape sequence \C can be used to match a single byte in UTF-8 mode, or
+a single 16-bit data unit in UTF-16 mode, but its use can lead to some strange
+effects because it breaks up multi-unit characters (see the description of \C
+in the
+pcrepattern
+documentation). The use of \C is not supported in the alternative matching
+function pcre[16]_dfa_exec(), nor is it supported in UTF mode by the JIT
+optimization of pcre[16]_exec(). If JIT optimization is requested for a
+UTF pattern that contains \C, it will not succeed, and so the matching will
+be carried out by the normal interpretive function.
+
+
+6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly
+test characters of any code value, but, by default, the characters that PCRE
+recognizes as digits, spaces, or word characters remain the same set as in
+non-UTF mode, all with values less than 256. This remains true even when PCRE
+is built to include Unicode property support, because to do otherwise would
+slow down PCRE in many common cases. Note in particular that this applies to
+\b and \B, because they are defined in terms of \w and \W. If you really
+want to test for a wider sense of, say, "digit", you can use explicit Unicode
+property tests such as \p{Nd}. Alternatively, if you set the PCRE_UCP option,
+the way that the character escapes work is changed so that Unicode properties
+are used to determine which characters match. There are more details in the
+section on
+generic character types
+in the
+pcrepattern
+documentation.
+
+
+7. Similarly, characters that match the POSIX named character classes are all
+low-valued characters, unless the PCRE_UCP option is set.
+
+
+8. However, the horizontal and vertical white space matching escapes (\h, \H,
+\v, and \V) do match all the appropriate Unicode characters, whether or not
+PCRE_UCP is set.
+
+
+9. Case-insensitive matching applies only to characters whose values are less
+than 128, unless PCRE is built with Unicode property support. Even when Unicode
+property support is available, PCRE still uses its own character tables when
+checking the case of low-valued characters, so as not to degrade performance.
+The Unicode property information is used only for characters with higher
+values. Furthermore, PCRE supports case-insensitive matching only when there is
+a one-to-one mapping between a letter's cases. There are a small number of
+many-to-one mappings in Unicode; these are not supported by PCRE.
+
There are also individual pages that summarize the interface for each function
-in the library:
+in the library. There is a single page for each pair of 8-bit/16-bit functions.
diff -Nru pcre3-8.12/doc/pcre-config.1 pcre3-8.31/doc/pcre-config.1
--- pcre3-8.12/doc/pcre-config.1 2007-04-18 09:05:55.000000000 +0000
+++ pcre3-8.31/doc/pcre-config.1 2012-03-31 16:13:48.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE-CONFIG 1
+.TH PCRE-CONFIG 1 "01 January 2012" "PCRE 8.30"
.SH NAME
pcre-config - program to return PCRE configuration
.SH SYNOPSIS
@@ -6,14 +6,19 @@
.sp
.B pcre-config [--prefix] [--exec-prefix] [--version] [--libs]
.ti +5n
-.B [--libs-posix] [--cflags] [--cflags-posix]
+.B [--libs16] [--libs-cpp] [--libs-posix] [--cflags]
+.ti +5n
+.B [--cflags-posix]
.
.
.SH DESCRIPTION
.rs
.sp
\fBpcre-config\fP returns the configuration of the installed PCRE
-libraries and the options required to compile a program to use them.
+libraries and the options required to compile a program to use them. Some of
+the options apply only to the 8-bit or 16-bit libraries, respectively, and are
+not available if only one of those libraries has been built. If an unavailable
+option is encountered, the "usage" information is output.
.
.
.SH OPTIONS
@@ -34,11 +39,20 @@
.TP 10
\fB--libs\fP
Writes to the standard output the command line options required to link
-with PCRE (\fB-lpcre\fP on many systems).
+with the 8-bit PCRE library (\fB-lpcre\fP on many systems).
+.TP 10
+\fB--libs16\fP
+Writes to the standard output the command line options required to link
+with the 16-bit PCRE library (\fB-lpcre16\fP on many systems).
+.TP 10
+\fB--libs-cpp\fP
+Writes to the standard output the command line options required to link with
+PCRE's C++ wrapper library (\fB-lpcrecpp\fP \fB-lpcre\fP on many
+systems).
.TP 10
\fB--libs-posix\fP
Writes to the standard output the command line options required to link with
-the PCRE posix emulation library (\fB-lpcreposix\fP \fB-lpcre\fP on many
+PCRE's POSIX API wrapper library (\fB-lpcreposix\fP \fB-lpcre\fP on many
systems).
.TP 10
\fB--cflags\fP
@@ -48,7 +62,7 @@
.TP 10
\fB--cflags-posix\fP
Writes to the standard output the command line options required to compile
-files that use the PCRE posix emulation library (this may include some \fB-I\fP
+files that use PCRE's POSIX API wrapper library (this may include some \fB-I\fP
options, but is blank on many systems).
.
.
@@ -62,12 +76,12 @@
.rs
.sp
This manual page was originally written by Mark Baker for the Debian GNU/Linux
-system. It has been slightly revised as a generic PCRE man page.
+system. It has been subsequently revised as a generic PCRE man page.
.
.
.SH REVISION
.rs
.sp
.nf
-Last updated: 18 April 2007
+Last updated: 01 January 2012
.fi
diff -Nru pcre3-8.12/doc/pcre-config.txt pcre3-8.31/doc/pcre-config.txt
--- pcre3-8.12/doc/pcre-config.txt 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/pcre-config.txt 2012-07-06 09:55:27.000000000 +0000
@@ -8,35 +8,49 @@
SYNOPSIS
pcre-config [--prefix] [--exec-prefix] [--version] [--libs]
- [--libs-posix] [--cflags] [--cflags-posix]
+ [--libs16] [--libs-cpp] [--libs-posix] [--cflags]
+ [--cflags-posix]
DESCRIPTION
pcre-config returns the configuration of the installed PCRE libraries
- and the options required to compile a program to use them.
+ and the options required to compile a program to use them. Some of the
+ options apply only to the 8-bit or 16-bit libraries, respectively, and
+ are not available if only one of those libraries has been built. If an
+ unavailable option is encountered, the "usage" information is output.
OPTIONS
--prefix Writes the directory prefix used in the PCRE installation for
- architecture independent files (/usr on many systems,
+ architecture independent files (/usr on many systems,
/usr/local on some systems) to the standard output.
--exec-prefix
Writes the directory prefix used in the PCRE installation for
- architecture dependent files (normally the same as --prefix)
+ architecture dependent files (normally the same as --prefix)
to the standard output.
- --version Writes the version number of the installed PCRE libraries to
+ --version Writes the version number of the installed PCRE libraries to
the standard output.
- --libs Writes to the standard output the command line options
- required to link with PCRE (-lpcre on many systems).
+ --libs Writes to the standard output the command line options
+ required to link with the 8-bit PCRE library (-lpcre on many
+ systems).
+
+ --libs16 Writes to the standard output the command line options
+ required to link with the 16-bit PCRE library (-lpcre16 on
+ many systems).
+
+ --libs-cpp
+ Writes to the standard output the command line options
+ required to link with PCRE's C++ wrapper library (-lpcrecpp
+ -lpcre on many systems).
--libs-posix
Writes to the standard output the command line options
- required to link with the PCRE posix emulation library
+ required to link with PCRE's POSIX API wrapper library
(-lpcreposix -lpcre on many systems).
--cflags Writes to the standard output the command line options
@@ -45,7 +59,7 @@
--cflags-posix
Writes to the standard output the command line options
- required to compile files that use the PCRE posix emulation
+ required to compile files that use PCRE's POSIX API wrapper
library (this may include some -I options, but is blank on
many systems).
@@ -58,10 +72,10 @@
AUTHOR
This manual page was originally written by Mark Baker for the Debian
- GNU/Linux system. It has been slightly revised as a generic PCRE man
- page.
+ GNU/Linux system. It has been subsequently revised as a generic PCRE
+ man page.
REVISION
- Last updated: 18 April 2007
+ Last updated: 01 January 2012
diff -Nru pcre3-8.12/doc/pcre.3 pcre3-8.31/doc/pcre.3
--- pcre3-8.12/doc/pcre.3 2011-01-11 16:28:57.000000000 +0000
+++ pcre3-8.31/doc/pcre.3 2012-03-31 16:31:44.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE 3
+.TH PCRE 3 "10 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH INTRODUCTION
@@ -11,10 +11,29 @@
support for one or two .NET and Oniguruma syntax items, and there is an option
for requesting some minor changes that give better JavaScript compatibility.
.P
+Starting with release 8.30, it is possible to compile two separate PCRE
+libraries: the original, which supports 8-bit character strings (including
+UTF-8 strings), and a second library that supports 16-bit character strings
+(including UTF-16 strings). The build process allows either one or both to be
+built. The majority of the work to make this possible was done by Zoltan
+Herczeg.
+.P
+The two libraries contain identical sets of functions, except that the names in
+the 16-bit library start with \fBpcre16_\fP instead of \fBpcre_\fP. To avoid
+over-complication and reduce the documentation maintenance load, most of the
+documentation describes the 8-bit library, with the differences for the 16-bit
+library described separately in the
+.\" HREF
+\fBpcre16\fP
+.\"
+page. References to functions or structures of the form \fIpcre[16]_xxx\fP
+should be read as meaning "\fIpcre_xxx\fP when using the 8-bit library and
+\fIpcre16_xxx\fP when using the 16-bit library".
+.P
The current implementation of PCRE corresponds approximately with Perl 5.12,
-including support for UTF-8 encoded strings and Unicode general category
-properties. However, UTF-8 and Unicode support has to be explicitly enabled; it
-is not the default. The Unicode tables correspond to Unicode release 5.2.0.
+including support for UTF-8/16 encoded strings and Unicode general category
+properties. However, UTF-8/16 and Unicode support has to be explicitly enabled;
+it is not the default. The Unicode tables correspond to Unicode release 6.0.0.
.P
In addition to the Perl-compatible matching function, PCRE contains an
alternative function that matches the same compiled patterns in a different
@@ -27,8 +46,8 @@
.P
PCRE is written in C and released as a C library. A number of people have
written wrappers and interfaces of various kinds. In particular, Google Inc.
-have provided a comprehensive C++ wrapper. This is now included as part of the
-PCRE distribution. The
+have provided a comprehensive C++ wrapper for the 8-bit library. This is now
+included as part of the PCRE distribution. The
.\" HREF
\fBpcrecpp\fP
.\"
@@ -68,13 +87,13 @@
found in the \fBREADME\fP and \fBNON-UNIX-USE\fP files in the source
distribution.
.P
-The library contains a number of undocumented internal functions and data
+The libraries contains a number of undocumented internal functions and data
tables that are used by more than one of the exported external functions, but
which are not intended for use by external callers. Their names all begin with
-"_pcre_", which hopefully will not provoke any name clashes. In some
-environments, it is possible to control which external symbols are exported
-when a shared library is built, and in these cases the undocumented symbols are
-not exported.
+"_pcre_" or "_pcre16_", which hopefully will not provoke any name clashes. In
+some environments, it is possible to control which external symbols are
+exported when a shared library is built, and in these cases the undocumented
+symbols are not exported.
.
.
.SH "USER DOCUMENTATION"
@@ -87,203 +106,33 @@
of searching. The sections are as follows:
.sp
pcre this document
+ pcre16 details of the 16-bit library
pcre-config show PCRE installation configuration information
pcreapi details of PCRE's native C API
pcrebuild options for building PCRE
pcrecallout details of the callout feature
pcrecompat discussion of Perl compatibility
- pcrecpp details of the C++ wrapper
+ pcrecpp details of the C++ wrapper for the 8-bit library
pcredemo a demonstration C program that uses PCRE
- pcregrep description of the \fBpcregrep\fP command
+ pcregrep description of the \fBpcregrep\fP command (8-bit only)
+ pcrejit discussion of the just-in-time optimization support
+ pcrelimits details of size and other limits
pcrematching discussion of the two matching algorithms
pcrepartial details of the partial matching facility
.\" JOIN
pcrepattern syntax and semantics of supported
regular expressions
pcreperform discussion of performance issues
- pcreposix the POSIX-compatible C API
+ pcreposix the POSIX-compatible C API for the 8-bit library
pcreprecompile details of saving and re-using precompiled patterns
pcresample discussion of the pcredemo program
pcrestack discussion of stack usage
pcresyntax quick syntax reference
pcretest description of the \fBpcretest\fP testing command
+ pcreunicode discussion of Unicode and UTF-8/16 support
.sp
In addition, in the "man" and HTML formats, there is a short page for each
-C library function, listing its arguments and results.
-.
-.
-.SH LIMITATIONS
-.rs
-.sp
-There are some size limitations in PCRE but it is hoped that they will never in
-practice be relevant.
-.P
-The maximum length of a compiled pattern is 65539 (sic) bytes if PCRE is
-compiled with the default internal linkage size of 2. If you want to process
-regular expressions that are truly enormous, you can compile PCRE with an
-internal linkage size of 3 or 4 (see the \fBREADME\fP file in the source
-distribution and the
-.\" HREF
-\fBpcrebuild\fP
-.\"
-documentation for details). In these cases the limit is substantially larger.
-However, the speed of execution is slower.
-.P
-All values in repeating quantifiers must be less than 65536.
-.P
-There is no limit to the number of parenthesized subpatterns, but there can be
-no more than 65535 capturing subpatterns.
-.P
-The maximum length of name for a named subpattern is 32 characters, and the
-maximum number of named subpatterns is 10000.
-.P
-The maximum length of a subject string is the largest positive number that an
-integer variable can hold. However, when using the traditional matching
-function, PCRE uses recursion to handle subpatterns and indefinite repetition.
-This means that the available stack space may limit the size of a subject
-string that can be processed by certain patterns. For a discussion of stack
-issues, see the
-.\" HREF
-\fBpcrestack\fP
-.\"
-documentation.
-.
-.
-.\" HTML
-.SH "UTF-8 AND UNICODE PROPERTY SUPPORT"
-.rs
-.sp
-From release 3.3, PCRE has had some support for character strings encoded in
-the UTF-8 format. For release 4.0 this was greatly extended to cover most
-common requirements, and in release 5.0 additional support for Unicode general
-category properties was added.
-.P
-In order process UTF-8 strings, you must build PCRE to include UTF-8 support in
-the code, and, in addition, you must call
-.\" HREF
-\fBpcre_compile()\fP
-.\"
-with the PCRE_UTF8 option flag, or the pattern must start with the sequence
-(*UTF8). When either of these is the case, both the pattern and any subject
-strings that are matched against it are treated as UTF-8 strings instead of
-strings of 1-byte characters.
-.P
-If you compile PCRE with UTF-8 support, but do not use it at run time, the
-library will be a bit bigger, but the additional run time overhead is limited
-to testing the PCRE_UTF8 flag occasionally, so should not be very big.
-.P
-If PCRE is built with Unicode character property support (which implies UTF-8
-support), the escape sequences \ep{..}, \eP{..}, and \eX are supported.
-The available properties that can be tested are limited to the general
-category properties such as Lu for an upper case letter or Nd for a decimal
-number, the Unicode script names such as Arabic or Han, and the derived
-properties Any and L&. A full list is given in the
-.\" HREF
-\fBpcrepattern\fP
-.\"
-documentation. Only the short names for properties are supported. For example,
-\ep{L} matches a letter. Its Perl synonym, \ep{Letter}, is not supported.
-Furthermore, in Perl, many properties may optionally be prefixed by "Is", for
-compatibility with Perl 5.6. PCRE does not support this.
-.
-.
-.\" HTML
-.SS "Validity of UTF-8 strings"
-.rs
-.sp
-When you set the PCRE_UTF8 flag, the strings passed as patterns and subjects
-are (by default) checked for validity on entry to the relevant functions. From
-release 7.3 of PCRE, the check is according the rules of RFC 3629, which are
-themselves derived from the Unicode specification. Earlier releases of PCRE
-followed the rules of RFC 2279, which allows the full range of 31-bit values (0
-to 0x7FFFFFFF). The current check allows only values in the range U+0 to
-U+10FFFF, excluding U+D800 to U+DFFF.
-.P
-The excluded code points are the "Low Surrogate Area" of Unicode, of which the
-Unicode Standard says this: "The Low Surrogate Area does not contain any
-character assignments, consequently no character code charts or namelists are
-provided for this area. Surrogates are reserved for use with UTF-16 and then
-must be used in pairs." The code points that are encoded by UTF-16 pairs are
-available as independent code points in the UTF-8 encoding. (In other words,
-the whole surrogate thing is a fudge for UTF-16 which unfortunately messes up
-UTF-8.)
-.P
-If an invalid UTF-8 string is passed to PCRE, an error return
-(PCRE_ERROR_BADUTF8) is given. In some situations, you may already know that
-your strings are valid, and therefore want to skip these checks in order to
-improve performance. If you set the PCRE_NO_UTF8_CHECK flag at compile time or
-at run time, PCRE assumes that the pattern or subject it is given
-(respectively) contains only valid UTF-8 codes. In this case, it does not
-diagnose an invalid UTF-8 string.
-.P
-If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, what
-happens depends on why the string is invalid. If the string conforms to the
-"old" definition of UTF-8 (RFC 2279), it is processed as a string of characters
-in the range 0 to 0x7FFFFFFF. In other words, apart from the initial validity
-test, PCRE (when in UTF-8 mode) handles strings according to the more liberal
-rules of RFC 2279. However, if the string does not even conform to RFC 2279,
-the result is undefined. Your program may crash.
-.P
-If you want to process strings of values in the full range 0 to 0x7FFFFFFF,
-encoded in a UTF-8-like manner as per the old RFC, you can set
-PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in this
-situation, you will have to apply your own validity check.
-.
-.
-.SS "General comments about UTF-8 mode"
-.rs
-.sp
-1. An unbraced hexadecimal escape sequence (such as \exb3) matches a two-byte
-UTF-8 character if the value is greater than 127.
-.P
-2. Octal numbers up to \e777 are recognized, and match two-byte UTF-8
-characters for values greater than \e177.
-.P
-3. Repeat quantifiers apply to complete UTF-8 characters, not to individual
-bytes, for example: \ex{100}{3}.
-.P
-4. The dot metacharacter matches one UTF-8 character instead of a single byte.
-.P
-5. The escape sequence \eC can be used to match a single byte in UTF-8 mode,
-but its use can lead to some strange effects. This facility is not available in
-the alternative matching function, \fBpcre_dfa_exec()\fP.
-.P
-6. The character escapes \eb, \eB, \ed, \eD, \es, \eS, \ew, and \eW correctly
-test characters of any code value, but, by default, the characters that PCRE
-recognizes as digits, spaces, or word characters remain the same set as before,
-all with values less than 256. This remains true even when PCRE is built to
-include Unicode property support, because to do otherwise would slow down PCRE
-in many common cases. Note in particular that this applies to \eb and \eB,
-because they are defined in terms of \ew and \eW. If you really want to test
-for a wider sense of, say, "digit", you can use explicit Unicode property tests
-such as \ep{Nd}. Alternatively, if you set the PCRE_UCP option, the way that
-the character escapes work is changed so that Unicode properties are used to
-determine which characters match. There are more details in the section on
-.\" HTML
-.\"
-generic character types
-.\"
-in the
-.\" HREF
-\fBpcrepattern\fP
-.\"
-documentation.
-.P
-7. Similarly, characters that match the POSIX named character classes are all
-low-valued characters, unless the PCRE_UCP option is set.
-.P
-8. However, the horizontal and vertical whitespace matching escapes (\eh, \eH,
-\ev, and \eV) do match all the appropriate Unicode characters, whether or not
-PCRE_UCP is set.
-.P
-9. Case-insensitive matching applies only to characters whose values are less
-than 128, unless PCRE is built with Unicode property support. Even when Unicode
-property support is available, PCRE still uses its own character tables when
-checking the case of low-valued characters, so as not to degrade performance.
-The Unicode property information is used only for characters with higher
-values. Furthermore, PCRE supports case-insensitive matching only when there is
-a one-to-one mapping between a letter's cases. There are a small number of
-many-to-one mappings in Unicode; these are not supported by PCRE.
+8-bit C library function, listing its arguments and results.
.
.
.SH AUTHOR
@@ -304,6 +153,6 @@
.rs
.sp
.nf
-Last updated: 13 November 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 10 January 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcre.txt pcre3-8.31/doc/pcre.txt
--- pcre3-8.12/doc/pcre.txt 2011-01-15 17:27:46.000000000 +0000
+++ pcre3-8.31/doc/pcre.txt 2012-07-06 09:55:28.000000000 +0000
@@ -25,11 +25,27 @@
items, and there is an option for requesting some minor changes that
give better JavaScript compatibility.
+ Starting with release 8.30, it is possible to compile two separate PCRE
+ libraries: the original, which supports 8-bit character strings
+ (including UTF-8 strings), and a second library that supports 16-bit
+ character strings (including UTF-16 strings). The build process allows
+ either one or both to be built. The majority of the work to make this
+ possible was done by Zoltan Herczeg.
+
+ The two libraries contain identical sets of functions, except that the
+ names in the 16-bit library start with pcre16_ instead of pcre_. To
+ avoid over-complication and reduce the documentation maintenance load,
+ most of the documentation describes the 8-bit library, with the differ-
+ ences for the 16-bit library described separately in the pcre16 page.
+ References to functions or structures of the form pcre[16]_xxx should
+ be read as meaning "pcre_xxx when using the 8-bit library and
+ pcre16_xxx when using the 16-bit library".
+
The current implementation of PCRE corresponds approximately with Perl
- 5.12, including support for UTF-8 encoded strings and Unicode general
- category properties. However, UTF-8 and Unicode support has to be
- explicitly enabled; it is not the default. The Unicode tables corre-
- spond to Unicode release 5.2.0.
+ 5.12, including support for UTF-8/16 encoded strings and Unicode gen-
+ eral category properties. However, UTF-8/16 and Unicode support has to
+ be explicitly enabled; it is not the default. The Unicode tables corre-
+ spond to Unicode release 6.0.0.
In addition to the Perl-compatible matching function, PCRE contains an
alternative function that matches the same compiled patterns in a dif-
@@ -39,218 +55,401 @@
PCRE is written in C and released as a C library. A number of people
have written wrappers and interfaces of various kinds. In particular,
- Google Inc. have provided a comprehensive C++ wrapper. This is now
- included as part of the PCRE distribution. The pcrecpp page has details
- of this interface. Other people's contributions can be found in the
- Contrib directory at the primary FTP site, which is:
+ Google Inc. have provided a comprehensive C++ wrapper for the 8-bit
+ library. This is now included as part of the PCRE distribution. The
+ pcrecpp page has details of this interface. Other people's contribu-
+ tions can be found in the Contrib directory at the primary FTP site,
+ which is:
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre
- Details of exactly which Perl regular expression features are and are
+ Details of exactly which Perl regular expression features are and are
not supported by PCRE are given in separate documents. See the pcrepat-
- tern and pcrecompat pages. There is a syntax summary in the pcresyntax
+ tern and pcrecompat pages. There is a syntax summary in the pcresyntax
page.
- Some features of PCRE can be included, excluded, or changed when the
- library is built. The pcre_config() function makes it possible for a
- client to discover which features are available. The features them-
- selves are described in the pcrebuild page. Documentation about build-
- ing PCRE for various operating systems can be found in the README and
+ Some features of PCRE can be included, excluded, or changed when the
+ library is built. The pcre_config() function makes it possible for a
+ client to discover which features are available. The features them-
+ selves are described in the pcrebuild page. Documentation about build-
+ ing PCRE for various operating systems can be found in the README and
NON-UNIX-USE files in the source distribution.
- The library contains a number of undocumented internal functions and
- data tables that are used by more than one of the exported external
- functions, but which are not intended for use by external callers.
- Their names all begin with "_pcre_", which hopefully will not provoke
- any name clashes. In some environments, it is possible to control which
- external symbols are exported when a shared library is built, and in
- these cases the undocumented symbols are not exported.
+ The libraries contains a number of undocumented internal functions and
+ data tables that are used by more than one of the exported external
+ functions, but which are not intended for use by external callers.
+ Their names all begin with "_pcre_" or "_pcre16_", which hopefully will
+ not provoke any name clashes. In some environments, it is possible to
+ control which external symbols are exported when a shared library is
+ built, and in these cases the undocumented symbols are not exported.
USER DOCUMENTATION
- The user documentation for PCRE comprises a number of different sec-
- tions. In the "man" format, each of these is a separate "man page". In
- the HTML format, each is a separate page, linked from the index page.
- In the plain text format, all the sections, except the pcredemo sec-
+ The user documentation for PCRE comprises a number of different sec-
+ tions. In the "man" format, each of these is a separate "man page". In
+ the HTML format, each is a separate page, linked from the index page.
+ In the plain text format, all the sections, except the pcredemo sec-
tion, are concatenated, for ease of searching. The sections are as fol-
lows:
pcre this document
+ pcre16 details of the 16-bit library
pcre-config show PCRE installation configuration information
pcreapi details of PCRE's native C API
pcrebuild options for building PCRE
pcrecallout details of the callout feature
pcrecompat discussion of Perl compatibility
- pcrecpp details of the C++ wrapper
+ pcrecpp details of the C++ wrapper for the 8-bit library
pcredemo a demonstration C program that uses PCRE
- pcregrep description of the pcregrep command
+ pcregrep description of the pcregrep command (8-bit only)
+ pcrejit discussion of the just-in-time optimization support
+ pcrelimits details of size and other limits
pcrematching discussion of the two matching algorithms
pcrepartial details of the partial matching facility
pcrepattern syntax and semantics of supported
regular expressions
pcreperform discussion of performance issues
- pcreposix the POSIX-compatible C API
+ pcreposix the POSIX-compatible C API for the 8-bit library
pcreprecompile details of saving and re-using precompiled patterns
pcresample discussion of the pcredemo program
pcrestack discussion of stack usage
pcresyntax quick syntax reference
pcretest description of the pcretest testing command
+ pcreunicode discussion of Unicode and UTF-8/16 support
- In addition, in the "man" and HTML formats, there is a short page for
- each C library function, listing its arguments and results.
+ In addition, in the "man" and HTML formats, there is a short page for
+ each 8-bit C library function, listing its arguments and results.
-LIMITATIONS
+AUTHOR
- There are some size limitations in PCRE but it is hoped that they will
- never in practice be relevant.
+ Philip Hazel
+ University Computing Service
+ Cambridge CB2 3QH, England.
- The maximum length of a compiled pattern is 65539 (sic) bytes if PCRE
- is compiled with the default internal linkage size of 2. If you want to
- process regular expressions that are truly enormous, you can compile
- PCRE with an internal linkage size of 3 or 4 (see the README file in
- the source distribution and the pcrebuild documentation for details).
- In these cases the limit is substantially larger. However, the speed
- of execution is slower.
+ Putting an actual email address here seems to have been a spam magnet,
+ so I've taken it away. If you want to email me, use my two initials,
+ followed by the two digits 10, at the domain cam.ac.uk.
- All values in repeating quantifiers must be less than 65536.
- There is no limit to the number of parenthesized subpatterns, but there
- can be no more than 65535 capturing subpatterns.
+REVISION
- The maximum length of name for a named subpattern is 32 characters, and
- the maximum number of named subpatterns is 10000.
+ Last updated: 10 January 2012
+ Copyright (c) 1997-2012 University of Cambridge.
+------------------------------------------------------------------------------
- The maximum length of a subject string is the largest positive number
- that an integer variable can hold. However, when using the traditional
- matching function, PCRE uses recursion to handle subpatterns and indef-
- inite repetition. This means that the available stack space may limit
- the size of a subject string that can be processed by certain patterns.
- For a discussion of stack issues, see the pcrestack documentation.
+PCRE(3) PCRE(3)
-UTF-8 AND UNICODE PROPERTY SUPPORT
- From release 3.3, PCRE has had some support for character strings
- encoded in the UTF-8 format. For release 4.0 this was greatly extended
- to cover most common requirements, and in release 5.0 additional sup-
- port for Unicode general category properties was added.
-
- In order process UTF-8 strings, you must build PCRE to include UTF-8
- support in the code, and, in addition, you must call pcre_compile()
- with the PCRE_UTF8 option flag, or the pattern must start with the
- sequence (*UTF8). When either of these is the case, both the pattern
- and any subject strings that are matched against it are treated as
- UTF-8 strings instead of strings of 1-byte characters.
-
- If you compile PCRE with UTF-8 support, but do not use it at run time,
- the library will be a bit bigger, but the additional run time overhead
- is limited to testing the PCRE_UTF8 flag occasionally, so should not be
- very big.
+NAME
+ PCRE - Perl-compatible regular expressions
- If PCRE is built with Unicode character property support (which implies
- UTF-8 support), the escape sequences \p{..}, \P{..}, and \X are sup-
- ported. The available properties that can be tested are limited to the
- general category properties such as Lu for an upper case letter or Nd
- for a decimal number, the Unicode script names such as Arabic or Han,
- and the derived properties Any and L&. A full list is given in the
- pcrepattern documentation. Only the short names for properties are sup-
- ported. For example, \p{L} matches a letter. Its Perl synonym, \p{Let-
- ter}, is not supported. Furthermore, in Perl, many properties may
- optionally be prefixed by "Is", for compatibility with Perl 5.6. PCRE
- does not support this.
+ #include
- Validity of UTF-8 strings
- When you set the PCRE_UTF8 flag, the strings passed as patterns and
- subjects are (by default) checked for validity on entry to the relevant
- functions. From release 7.3 of PCRE, the check is according the rules
- of RFC 3629, which are themselves derived from the Unicode specifica-
- tion. Earlier releases of PCRE followed the rules of RFC 2279, which
- allows the full range of 31-bit values (0 to 0x7FFFFFFF). The current
- check allows only values in the range U+0 to U+10FFFF, excluding U+D800
- to U+DFFF.
-
- The excluded code points are the "Low Surrogate Area" of Unicode, of
- which the Unicode Standard says this: "The Low Surrogate Area does not
- contain any character assignments, consequently no character code
- charts or namelists are provided for this area. Surrogates are reserved
- for use with UTF-16 and then must be used in pairs." The code points
- that are encoded by UTF-16 pairs are available as independent code
- points in the UTF-8 encoding. (In other words, the whole surrogate
- thing is a fudge for UTF-16 which unfortunately messes up UTF-8.)
-
- If an invalid UTF-8 string is passed to PCRE, an error return
- (PCRE_ERROR_BADUTF8) is given. In some situations, you may already know
- that your strings are valid, and therefore want to skip these checks in
- order to improve performance. If you set the PCRE_NO_UTF8_CHECK flag at
- compile time or at run time, PCRE assumes that the pattern or subject
- it is given (respectively) contains only valid UTF-8 codes. In this
- case, it does not diagnose an invalid UTF-8 string.
+PCRE 16-BIT API BASIC FUNCTIONS
- If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set,
- what happens depends on why the string is invalid. If the string con-
- forms to the "old" definition of UTF-8 (RFC 2279), it is processed as a
- string of characters in the range 0 to 0x7FFFFFFF. In other words,
- apart from the initial validity test, PCRE (when in UTF-8 mode) handles
- strings according to the more liberal rules of RFC 2279. However, if
- the string does not even conform to RFC 2279, the result is undefined.
- Your program may crash.
+ pcre16 *pcre16_compile(PCRE_SPTR16 pattern, int options,
+ const char **errptr, int *erroffset,
+ const unsigned char *tableptr);
- If you want to process strings of values in the full range 0 to
- 0x7FFFFFFF, encoded in a UTF-8-like manner as per the old RFC, you can
- set PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in
- this situation, you will have to apply your own validity check.
+ pcre16 *pcre16_compile2(PCRE_SPTR16 pattern, int options,
+ int *errorcodeptr,
+ const char **errptr, int *erroffset,
+ const unsigned char *tableptr);
- General comments about UTF-8 mode
+ pcre16_extra *pcre16_study(const pcre16 *code, int options,
+ const char **errptr);
- 1. An unbraced hexadecimal escape sequence (such as \xb3) matches a
- two-byte UTF-8 character if the value is greater than 127.
+ void pcre16_free_study(pcre16_extra *extra);
- 2. Octal numbers up to \777 are recognized, and match two-byte UTF-8
- characters for values greater than \177.
+ int pcre16_exec(const pcre16 *code, const pcre16_extra *extra,
+ PCRE_SPTR16 subject, int length, int startoffset,
+ int options, int *ovector, int ovecsize);
- 3. Repeat quantifiers apply to complete UTF-8 characters, not to indi-
- vidual bytes, for example: \x{100}{3}.
+ int pcre16_dfa_exec(const pcre16 *code, const pcre16_extra *extra,
+ PCRE_SPTR16 subject, int length, int startoffset,
+ int options, int *ovector, int ovecsize,
+ int *workspace, int wscount);
- 4. The dot metacharacter matches one UTF-8 character instead of a sin-
- gle byte.
- 5. The escape sequence \C can be used to match a single byte in UTF-8
- mode, but its use can lead to some strange effects. This facility is
- not available in the alternative matching function, pcre_dfa_exec().
+PCRE 16-BIT API STRING EXTRACTION FUNCTIONS
- 6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly
- test characters of any code value, but, by default, the characters that
- PCRE recognizes as digits, spaces, or word characters remain the same
- set as before, all with values less than 256. This remains true even
- when PCRE is built to include Unicode property support, because to do
- otherwise would slow down PCRE in many common cases. Note in particular
- that this applies to \b and \B, because they are defined in terms of \w
- and \W. If you really want to test for a wider sense of, say, "digit",
- you can use explicit Unicode property tests such as \p{Nd}. Alterna-
- tively, if you set the PCRE_UCP option, the way that the character
- escapes work is changed so that Unicode properties are used to deter-
- mine which characters match. There are more details in the section on
- generic character types in the pcrepattern documentation.
+ int pcre16_copy_named_substring(const pcre16 *code,
+ PCRE_SPTR16 subject, int *ovector,
+ int stringcount, PCRE_SPTR16 stringname,
+ PCRE_UCHAR16 *buffer, int buffersize);
- 7. Similarly, characters that match the POSIX named character classes
- are all low-valued characters, unless the PCRE_UCP option is set.
+ int pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector,
+ int stringcount, int stringnumber, PCRE_UCHAR16 *buffer,
+ int buffersize);
- 8. However, the horizontal and vertical whitespace matching escapes
- (\h, \H, \v, and \V) do match all the appropriate Unicode characters,
- whether or not PCRE_UCP is set.
+ int pcre16_get_named_substring(const pcre16 *code,
+ PCRE_SPTR16 subject, int *ovector,
+ int stringcount, PCRE_SPTR16 stringname,
+ PCRE_SPTR16 *stringptr);
- 9. Case-insensitive matching applies only to characters whose values
- are less than 128, unless PCRE is built with Unicode property support.
- Even when Unicode property support is available, PCRE still uses its
- own character tables when checking the case of low-valued characters,
- so as not to degrade performance. The Unicode property information is
- used only for characters with higher values. Furthermore, PCRE supports
- case-insensitive matching only when there is a one-to-one mapping
- between a letter's cases. There are a small number of many-to-one map-
- pings in Unicode; these are not supported by PCRE.
+ int pcre16_get_stringnumber(const pcre16 *code,
+ PCRE_SPTR16 name);
+
+ int pcre16_get_stringtable_entries(const pcre16 *code,
+ PCRE_SPTR16 name, PCRE_UCHAR16 **first, PCRE_UCHAR16 **last);
+
+ int pcre16_get_substring(PCRE_SPTR16 subject, int *ovector,
+ int stringcount, int stringnumber,
+ PCRE_SPTR16 *stringptr);
+
+ int pcre16_get_substring_list(PCRE_SPTR16 subject,
+ int *ovector, int stringcount, PCRE_SPTR16 **listptr);
+
+ void pcre16_free_substring(PCRE_SPTR16 stringptr);
+
+ void pcre16_free_substring_list(PCRE_SPTR16 *stringptr);
+
+
+PCRE 16-BIT API AUXILIARY FUNCTIONS
+
+ pcre16_jit_stack *pcre16_jit_stack_alloc(int startsize, int maxsize);
+
+ void pcre16_jit_stack_free(pcre16_jit_stack *stack);
+
+ void pcre16_assign_jit_stack(pcre16_extra *extra,
+ pcre16_jit_callback callback, void *data);
+
+ const unsigned char *pcre16_maketables(void);
+
+ int pcre16_fullinfo(const pcre16 *code, const pcre16_extra *extra,
+ int what, void *where);
+
+ int pcre16_refcount(pcre16 *code, int adjust);
+
+ int pcre16_config(int what, void *where);
+
+ const char *pcre16_version(void);
+
+ int pcre16_pattern_to_host_byte_order(pcre16 *code,
+ pcre16_extra *extra, const unsigned char *tables);
+
+
+PCRE 16-BIT API INDIRECTED FUNCTIONS
+
+ void *(*pcre16_malloc)(size_t);
+
+ void (*pcre16_free)(void *);
+
+ void *(*pcre16_stack_malloc)(size_t);
+
+ void (*pcre16_stack_free)(void *);
+
+ int (*pcre16_callout)(pcre16_callout_block *);
+
+
+PCRE 16-BIT API 16-BIT-ONLY FUNCTION
+
+ int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output,
+ PCRE_SPTR16 input, int length, int *byte_order,
+ int keep_boms);
+
+
+THE PCRE 16-BIT LIBRARY
+
+ Starting with release 8.30, it is possible to compile a PCRE library
+ that supports 16-bit character strings, including UTF-16 strings, as
+ well as or instead of the original 8-bit library. The majority of the
+ work to make this possible was done by Zoltan Herczeg. The two
+ libraries contain identical sets of functions, used in exactly the same
+ way. Only the names of the functions and the data types of their argu-
+ ments and results are different. To avoid over-complication and reduce
+ the documentation maintenance load, most of the PCRE documentation
+ describes the 8-bit library, with only occasional references to the
+ 16-bit library. This page describes what is different when you use the
+ 16-bit library.
+
+ WARNING: A single application can be linked with both libraries, but
+ you must take care when processing any particular pattern to use func-
+ tions from just one library. For example, if you want to study a pat-
+ tern that was compiled with pcre16_compile(), you must do so with
+ pcre16_study(), not pcre_study(), and you must free the study data with
+ pcre16_free_study().
+
+
+THE HEADER FILE
+
+ There is only one header file, pcre.h. It contains prototypes for all
+ the functions in both libraries, as well as definitions of flags,
+ structures, error codes, etc.
+
+
+THE LIBRARY NAME
+
+ In Unix-like systems, the 16-bit library is called libpcre16, and can
+ normally be accesss by adding -lpcre16 to the command for linking an
+ application that uses PCRE.
+
+
+STRING TYPES
+
+ In the 8-bit library, strings are passed to PCRE library functions as
+ vectors of bytes with the C type "char *". In the 16-bit library,
+ strings are passed as vectors of unsigned 16-bit quantities. The macro
+ PCRE_UCHAR16 specifies an appropriate data type, and PCRE_SPTR16 is
+ defined as "const PCRE_UCHAR16 *". In very many environments, "short
+ int" is a 16-bit data type. When PCRE is built, it defines PCRE_UCHAR16
+ as "short int", but checks that it really is a 16-bit data type. If it
+ is not, the build fails with an error message telling the maintainer to
+ modify the definition appropriately.
+
+
+STRUCTURE TYPES
+
+ The types of the opaque structures that are used for compiled 16-bit
+ patterns and JIT stacks are pcre16 and pcre16_jit_stack respectively.
+ The type of the user-accessible structure that is returned by
+ pcre16_study() is pcre16_extra, and the type of the structure that is
+ used for passing data to a callout function is pcre16_callout_block.
+ These structures contain the same fields, with the same names, as their
+ 8-bit counterparts. The only difference is that pointers to character
+ strings are 16-bit instead of 8-bit types.
+
+
+16-BIT FUNCTIONS
+
+ For every function in the 8-bit library there is a corresponding func-
+ tion in the 16-bit library with a name that starts with pcre16_ instead
+ of pcre_. The prototypes are listed above. In addition, there is one
+ extra function, pcre16_utf16_to_host_byte_order(). This is a utility
+ function that converts a UTF-16 character string to host byte order if
+ necessary. The other 16-bit functions expect the strings they are
+ passed to be in host byte order.
+
+ The input and output arguments of pcre16_utf16_to_host_byte_order() may
+ point to the same address, that is, conversion in place is supported.
+ The output buffer must be at least as long as the input.
+
+ The length argument specifies the number of 16-bit data units in the
+ input string; a negative value specifies a zero-terminated string.
+
+ If byte_order is NULL, it is assumed that the string starts off in host
+ byte order. This may be changed by byte-order marks (BOMs) anywhere in
+ the string (commonly as the first character).
+
+ If byte_order is not NULL, a non-zero value of the integer to which it
+ points means that the input starts off in host byte order, otherwise
+ the opposite order is assumed. Again, BOMs in the string can change
+ this. The final byte order is passed back at the end of processing.
+
+ If keep_boms is not zero, byte-order mark characters (0xfeff) are
+ copied into the output string. Otherwise they are discarded.
+
+ The result of the function is the number of 16-bit units placed into
+ the output buffer, including the zero terminator if the string was
+ zero-terminated.
+
+
+SUBJECT STRING OFFSETS
+
+ The offsets within subject strings that are returned by the matching
+ functions are in 16-bit units rather than bytes.
+
+
+NAMED SUBPATTERNS
+
+ The name-to-number translation table that is maintained for named sub-
+ patterns uses 16-bit characters. The pcre16_get_stringtable_entries()
+ function returns the length of each entry in the table as the number of
+ 16-bit data units.
+
+
+OPTION NAMES
+
+ There are two new general option names, PCRE_UTF16 and
+ PCRE_NO_UTF16_CHECK, which correspond to PCRE_UTF8 and
+ PCRE_NO_UTF8_CHECK in the 8-bit library. In fact, these new options
+ define the same bits in the options word. There is a discussion about
+ the validity of UTF-16 strings in the pcreunicode page.
+
+ For the pcre16_config() function there is an option PCRE_CONFIG_UTF16
+ that returns 1 if UTF-16 support is configured, otherwise 0. If this
+ option is given to pcre_config(), or if the PCRE_CONFIG_UTF8 option is
+ given to pcre16_config(), the result is the PCRE_ERROR_BADOPTION error.
+
+
+CHARACTER CODES
+
+ In 16-bit mode, when PCRE_UTF16 is not set, character values are
+ treated in the same way as in 8-bit, non UTF-8 mode, except, of course,
+ that they can range from 0 to 0xffff instead of 0 to 0xff. Character
+ types for characters less than 0xff can therefore be influenced by the
+ locale in the same way as before. Characters greater than 0xff have
+ only one case, and no "type" (such as letter or digit).
+
+ In UTF-16 mode, the character code is Unicode, in the range 0 to
+ 0x10ffff, with the exception of values in the range 0xd800 to 0xdfff
+ because those are "surrogate" values that are used in pairs to encode
+ values greater than 0xffff.
+
+ A UTF-16 string can indicate its endianness by special code knows as a
+ byte-order mark (BOM). The PCRE functions do not handle this, expecting
+ strings to be in host byte order. A utility function called
+ pcre16_utf16_to_host_byte_order() is provided to help with this (see
+ above).
+
+
+ERROR NAMES
+
+ The errors PCRE_ERROR_BADUTF16_OFFSET and PCRE_ERROR_SHORTUTF16 corre-
+ spond to their 8-bit counterparts. The error PCRE_ERROR_BADMODE is
+ given when a compiled pattern is passed to a function that processes
+ patterns in the other mode, for example, if a pattern compiled with
+ pcre_compile() is passed to pcre16_exec().
+
+ There are new error codes whose names begin with PCRE_UTF16_ERR for
+ invalid UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for
+ UTF-8 strings that are described in the section entitled "Reason codes
+ for invalid UTF-8 strings" in the main pcreapi page. The UTF-16 errors
+ are:
+
+ PCRE_UTF16_ERR1 Missing low surrogate at end of string
+ PCRE_UTF16_ERR2 Invalid low surrogate follows high surrogate
+ PCRE_UTF16_ERR3 Isolated low surrogate
+ PCRE_UTF16_ERR4 Invalid character 0xfffe
+
+
+ERROR TEXTS
+
+ If there is an error while compiling a pattern, the error text that is
+ passed back by pcre16_compile() or pcre16_compile2() is still an 8-bit
+ character string, zero-terminated.
+
+
+CALLOUTS
+
+ The subject and mark fields in the callout block that is passed to a
+ callout function point to 16-bit vectors.
+
+
+TESTING
+
+ The pcretest program continues to operate with 8-bit input and output
+ files, but it can be used for testing the 16-bit library. If it is run
+ with the command line option -16, patterns and subject strings are con-
+ verted from 8-bit to 16-bit before being passed to PCRE, and the 16-bit
+ library functions are used instead of the 8-bit ones. Returned 16-bit
+ strings are converted to 8-bit for output. If the 8-bit library was not
+ compiled, pcretest defaults to 16-bit and the -16 option is ignored.
+
+ When PCRE is being built, the RunTest script that is called by "make
+ check" uses the pcretest -C option to discover which of the 8-bit and
+ 16-bit libraries has been built, and runs the tests appropriately.
+
+
+NOT SUPPORTED IN 16-BIT MODE
+
+ Not all the features of the 8-bit library are available with the 16-bit
+ library. The C++ and POSIX wrapper functions support only the 8-bit
+ library, and the pcregrep program is at present 8-bit only.
AUTHOR
@@ -259,15 +458,11 @@
University Computing Service
Cambridge CB2 3QH, England.
- Putting an actual email address here seems to have been a spam magnet,
- so I've taken it away. If you want to email me, use my two initials,
- followed by the two digits 10, at the domain cam.ac.uk.
-
REVISION
- Last updated: 13 November 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 14 April 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
@@ -307,46 +502,89 @@
is not described.
+BUILDING 8-BIT and 16-BIT LIBRARIES
+
+ By default, a library called libpcre is built, containing functions
+ that take string arguments contained in vectors of bytes, either as
+ single-byte characters, or interpreted as UTF-8 strings. You can also
+ build a separate library, called libpcre16, in which strings are con-
+ tained in vectors of 16-bit data units and interpreted either as sin-
+ gle-unit characters or UTF-16 strings, by adding
+
+ --enable-pcre16
+
+ to the configure command. If you do not want the 8-bit library, add
+
+ --disable-pcre8
+
+ as well. At least one of the two libraries must be built. Note that the
+ C++ and POSIX wrappers are for the 8-bit library only, and that pcre-
+ grep is an 8-bit program. None of these are built if you select only
+ the 16-bit library.
+
+
+BUILDING SHARED AND STATIC LIBRARIES
+
+ The PCRE building process uses libtool to build both shared and static
+ Unix libraries by default. You can suppress one of these by adding one
+ of
+
+ --disable-shared
+ --disable-static
+
+ to the configure command, as required.
+
+
C++ SUPPORT
- By default, the configure script will search for a C++ compiler and C++
- header files. If it finds them, it automatically builds the C++ wrapper
- library for PCRE. You can disable this by adding
+ By default, if the 8-bit library is being built, the configure script
+ will search for a C++ compiler and C++ header files. If it finds them,
+ it automatically builds the C++ wrapper library (which supports only
+ 8-bit strings). You can disable this by adding
--disable-cpp
to the configure command.
-UTF-8 SUPPORT
+UTF-8 and UTF-16 SUPPORT
- To build PCRE with support for UTF-8 Unicode character strings, add
+ To build PCRE with support for UTF Unicode character strings, add
- --enable-utf8
+ --enable-utf
- to the configure command. Of itself, this does not make PCRE treat
- strings as UTF-8. As well as compiling PCRE with this option, you also
- have have to set the PCRE_UTF8 option when you call the pcre_compile()
- or pcre_compile2() functions.
-
- If you set --enable-utf8 when compiling in an EBCDIC environment, PCRE
- expects its input to be either ASCII or UTF-8 (depending on the runtime
- option). It is not possible to support both EBCDIC and UTF-8 codes in
- the same version of the library. Consequently, --enable-utf8 and
+ to the configure command. This setting applies to both libraries,
+ adding support for UTF-8 to the 8-bit library and support for UTF-16 to
+ the 16-bit library. There are no separate options for enabling UTF-8
+ and UTF-16 independently because that would allow ridiculous settings
+ such as requesting UTF-16 support while building only the 8-bit
+ library. It is not possible to build one library with UTF support and
+ the other without in the same configuration. (For backwards compatibil-
+ ity, --enable-utf8 is a synonym of --enable-utf.)
+
+ Of itself, this setting does not make PCRE treat strings as UTF-8 or
+ UTF-16. As well as compiling PCRE with this option, you also have have
+ to set the PCRE_UTF8 or PCRE_UTF16 option when you call one of the pat-
+ tern compiling functions.
+
+ If you set --enable-utf when compiling in an EBCDIC environment, PCRE
+ expects its input to be either ASCII or UTF-8 (depending on the run-
+ time option). It is not possible to support both EBCDIC and UTF-8 codes
+ in the same version of the library. Consequently, --enable-utf and
--enable-ebcdic are mutually exclusive.
UNICODE CHARACTER PROPERTY SUPPORT
- UTF-8 support allows PCRE to process character values greater than 255
- in the strings that it handles. On its own, however, it does not pro-
- vide any facilities for accessing the properties of such characters. If
- you want to be able to use the pattern escapes \P, \p, and \X, which
- refer to Unicode character properties, you must add
+ UTF support allows the libraries to process character codepoints up to
+ 0x10ffff in the strings that they handle. On its own, however, it does
+ not provide any facilities for accessing the properties of such charac-
+ ters. If you want to be able to use the pattern escapes \P, \p, and \X,
+ which refer to Unicode character properties, you must add
--enable-unicode-properties
- to the configure command. This implies UTF-8 support, even if you have
+ to the configure command. This implies UTF support, even if you have
not explicitly requested it.
Including Unicode property support adds around 30K of tables to the
@@ -354,6 +592,23 @@
are supported. Details are given in the pcrepattern documentation.
+JUST-IN-TIME COMPILER SUPPORT
+
+ Just-in-time compiler support is included in the build by specifying
+
+ --enable-jit
+
+ This support is available only for certain hardware architectures. If
+ this option is set for an unsupported architecture, a compile time
+ error occurs. See the pcrejit documentation for a discussion of JIT
+ usage. When JIT support is enabled, pcregrep automatically makes use of
+ it, unless you add
+
+ --disable-pcregrep-jit
+
+ to the "configure" command.
+
+
CODE VALUE OF NEWLINE
By default, PCRE interprets the linefeed (LF) character as indicating
@@ -400,28 +655,16 @@
functions are called.
-BUILDING SHARED AND STATIC LIBRARIES
-
- The PCRE building process uses libtool to build both shared and static
- Unix libraries by default. You can suppress one of these by adding one
- of
-
- --disable-shared
- --disable-static
-
- to the configure command, as required.
-
-
POSIX MALLOC USAGE
- When PCRE is called through the POSIX interface (see the pcreposix doc-
- umentation), additional working storage is required for holding the
- pointers to capturing substrings, because PCRE requires three integers
- per substring, whereas the POSIX interface provides only two. If the
- number of expected substrings is small, the wrapper function uses space
- on the stack, because this is faster than using malloc() for each call.
- The default threshold above which the stack is no longer used is 10; it
- can be changed by adding a setting such as
+ When the 8-bit library is called through the POSIX interface (see the
+ pcreposix documentation), additional working storage is required for
+ holding the pointers to capturing substrings, because PCRE requires
+ three integers per substring, whereas the POSIX interface provides only
+ two. If the number of expected substrings is small, the wrapper func-
+ tion uses space on the stack, because this is faster than using mal-
+ loc() for each call. The default threshold above which the stack is no
+ longer used is 10; it can be changed by adding a setting such as
--with-posix-malloc-threshold=20
@@ -435,107 +678,108 @@
nation metacharacter). By default, two-byte values are used for these
offsets, leading to a maximum size for a compiled pattern of around
64K. This is sufficient to handle all but the most gigantic patterns.
- Nevertheless, some people do want to process truyl enormous patterns,
+ Nevertheless, some people do want to process truly enormous patterns,
so it is possible to compile PCRE to use three-byte or four-byte off-
sets by adding a setting such as
--with-link-size=3
- to the configure command. The value given must be 2, 3, or 4. Using
- longer offsets slows down the operation of PCRE because it has to load
- additional bytes when handling them.
+ to the configure command. The value given must be 2, 3, or 4. For the
+ 16-bit library, a value of 3 is rounded up to 4. Using longer offsets
+ slows down the operation of PCRE because it has to load additional data
+ when handling them.
AVOIDING EXCESSIVE STACK USAGE
When matching with the pcre_exec() function, PCRE implements backtrack-
- ing by making recursive calls to an internal function called match().
- In environments where the size of the stack is limited, this can se-
- verely limit PCRE's operation. (The Unix environment does not usually
+ ing by making recursive calls to an internal function called match().
+ In environments where the size of the stack is limited, this can se-
+ verely limit PCRE's operation. (The Unix environment does not usually
suffer from this problem, but it may sometimes be necessary to increase
- the maximum stack size. There is a discussion in the pcrestack docu-
- mentation.) An alternative approach to recursion that uses memory from
- the heap to remember data, instead of using recursive function calls,
- has been implemented to work round the problem of limited stack size.
+ the maximum stack size. There is a discussion in the pcrestack docu-
+ mentation.) An alternative approach to recursion that uses memory from
+ the heap to remember data, instead of using recursive function calls,
+ has been implemented to work round the problem of limited stack size.
If you want to build a version of PCRE that works this way, add
--disable-stack-for-recursion
- to the configure command. With this configuration, PCRE will use the
- pcre_stack_malloc and pcre_stack_free variables to call memory manage-
- ment functions. By default these point to malloc() and free(), but you
+ to the configure command. With this configuration, PCRE will use the
+ pcre_stack_malloc and pcre_stack_free variables to call memory manage-
+ ment functions. By default these point to malloc() and free(), but you
can replace the pointers so that your own functions are used instead.
- Separate functions are provided rather than using pcre_malloc and
- pcre_free because the usage is very predictable: the block sizes
- requested are always the same, and the blocks are always freed in
- reverse order. A calling program might be able to implement optimized
- functions that perform better than malloc() and free(). PCRE runs
+ Separate functions are provided rather than using pcre_malloc and
+ pcre_free because the usage is very predictable: the block sizes
+ requested are always the same, and the blocks are always freed in
+ reverse order. A calling program might be able to implement optimized
+ functions that perform better than malloc() and free(). PCRE runs
noticeably more slowly when built in this way. This option affects only
the pcre_exec() function; it is not relevant for pcre_dfa_exec().
LIMITING PCRE RESOURCE USAGE
- Internally, PCRE has a function called match(), which it calls repeat-
- edly (sometimes recursively) when matching a pattern with the
- pcre_exec() function. By controlling the maximum number of times this
- function may be called during a single matching operation, a limit can
- be placed on the resources used by a single call to pcre_exec(). The
- limit can be changed at run time, as described in the pcreapi documen-
- tation. The default is 10 million, but this can be changed by adding a
+ Internally, PCRE has a function called match(), which it calls repeat-
+ edly (sometimes recursively) when matching a pattern with the
+ pcre_exec() function. By controlling the maximum number of times this
+ function may be called during a single matching operation, a limit can
+ be placed on the resources used by a single call to pcre_exec(). The
+ limit can be changed at run time, as described in the pcreapi documen-
+ tation. The default is 10 million, but this can be changed by adding a
setting such as
--with-match-limit=500000
- to the configure command. This setting has no effect on the
+ to the configure command. This setting has no effect on the
pcre_dfa_exec() matching function.
- In some environments it is desirable to limit the depth of recursive
+ In some environments it is desirable to limit the depth of recursive
calls of match() more strictly than the total number of calls, in order
- to restrict the maximum amount of stack (or heap, if --disable-stack-
+ to restrict the maximum amount of stack (or heap, if --disable-stack-
for-recursion is specified) that is used. A second limit controls this;
- it defaults to the value that is set for --with-match-limit, which
- imposes no additional constraints. However, you can set a lower limit
+ it defaults to the value that is set for --with-match-limit, which
+ imposes no additional constraints. However, you can set a lower limit
by adding, for example,
--with-match-limit-recursion=10000
- to the configure command. This value can also be overridden at run
+ to the configure command. This value can also be overridden at run
time.
CREATING CHARACTER TABLES AT BUILD TIME
- PCRE uses fixed tables for processing characters whose code values are
- less than 256. By default, PCRE is built with a set of tables that are
- distributed in the file pcre_chartables.c.dist. These tables are for
+ PCRE uses fixed tables for processing characters whose code values are
+ less than 256. By default, PCRE is built with a set of tables that are
+ distributed in the file pcre_chartables.c.dist. These tables are for
ASCII codes only. If you add
--enable-rebuild-chartables
- to the configure command, the distributed tables are no longer used.
- Instead, a program called dftables is compiled and run. This outputs
+ to the configure command, the distributed tables are no longer used.
+ Instead, a program called dftables is compiled and run. This outputs
the source for new set of tables, created in the default locale of your
- C runtime system. (This method of replacing the tables does not work if
- you are cross compiling, because dftables is run on the local host. If
- you need to create alternative tables when cross compiling, you will
+ C run-time system. (This method of replacing the tables does not work
+ if you are cross compiling, because dftables is run on the local host.
+ If you need to create alternative tables when cross compiling, you will
have to do so "by hand".)
USING EBCDIC CODE
- PCRE assumes by default that it will run in an environment where the
- character code is ASCII (or Unicode, which is a superset of ASCII).
- This is the case for most computer operating systems. PCRE can, how-
+ PCRE assumes by default that it will run in an environment where the
+ character code is ASCII (or Unicode, which is a superset of ASCII).
+ This is the case for most computer operating systems. PCRE can, how-
ever, be compiled to run in an EBCDIC environment by adding
--enable-ebcdic
to the configure command. This setting implies --enable-rebuild-charta-
- bles. You should only use it if you know that you are in an EBCDIC
- environment (for example, an IBM mainframe operating system). The
- --enable-ebcdic option is incompatible with --enable-utf8.
+ bles. You should only use it if you know that you are in an EBCDIC
+ environment (for example, an IBM mainframe operating system). The
+ --enable-ebcdic option is incompatible with --enable-utf.
PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT
@@ -548,10 +792,26 @@
--enable-pcregrep-libbz2
to the configure command. These options naturally require that the rel-
- evant libraries are installed on your system. Configuration will fail
+ evant libraries are installed on your system. Configuration will fail
if they are not.
+PCREGREP BUFFER SIZE
+
+ pcregrep uses an internal buffer to hold a "window" on the file it is
+ scanning, in order to be able to output "before" and "after" lines when
+ it finds a match. The size of the buffer is controlled by a parameter
+ whose default value is 20K. The buffer itself is three times this size,
+ but because of the way it is used for holding "before" lines, the long-
+ est line that is guaranteed to be processable is the parameter size.
+ You can change the default parameter value by adding, for example,
+
+ --with-pcregrep-bufsize=50K
+
+ to the configure command. The caller of pcregrep can, however, override
+ this value by specifying a run-time option.
+
+
PCRETEST OPTION FOR LIBREADLINE SUPPORT
If you add
@@ -585,7 +845,7 @@
SEE ALSO
- pcreapi(3), pcre_config(3).
+ pcreapi(3), pcre16, pcre_config(3).
AUTHOR
@@ -597,8 +857,8 @@
REVISION
- Last updated: 29 September 2009
- Copyright (c) 1997-2009 University of Cambridge.
+ Last updated: 07 January 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
@@ -614,13 +874,15 @@
This document describes the two different algorithms that are available
in PCRE for matching a compiled regular expression against a given sub-
ject string. The "standard" algorithm is the one provided by the
- pcre_exec() function. This works in the same was as Perl's matching
- function, and provides a Perl-compatible matching operation.
-
- An alternative algorithm is provided by the pcre_dfa_exec() function;
- this operates in a different way, and is not Perl-compatible. It has
- advantages and disadvantages compared with the standard algorithm, and
- these are described below.
+ pcre_exec() and pcre16_exec() functions. These work in the same was as
+ Perl's matching function, and provide a Perl-compatible matching opera-
+ tion. The just-in-time (JIT) optimization that is described in the
+ pcrejit documentation is compatible with these functions.
+
+ An alternative algorithm is provided by the pcre_dfa_exec() and
+ pcre16_dfa_exec() functions; they operate in a different way, and are
+ not Perl-compatible. This alternative has advantages and disadvantages
+ compared with the standard algorithm, and these are described below.
When there is only one possible way in which a given subject string can
match a pattern, the two algorithms give the same answer. A difference
@@ -748,42 +1010,43 @@
6. Callouts are supported, but the value of the capture_top field is
always 1, and the value of the capture_last field is always -1.
- 7. The \C escape sequence, which (in the standard algorithm) matches a
- single byte, even in UTF-8 mode, is not supported because the alterna-
- tive algorithm moves through the subject string one character at a
- time, for all active paths through the tree.
+ 7. The \C escape sequence, which (in the standard algorithm) always
+ matches a single data unit, even in UTF-8 or UTF-16 modes, is not sup-
+ ported in these modes, because the alternative algorithm moves through
+ the subject string one character (not data unit) at a time, for all
+ active paths through the tree.
- 8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE)
- are not supported. (*FAIL) is supported, and behaves like a failing
+ 8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE)
+ are not supported. (*FAIL) is supported, and behaves like a failing
negative assertion.
ADVANTAGES OF THE ALTERNATIVE ALGORITHM
- Using the alternative matching algorithm provides the following advan-
+ Using the alternative matching algorithm provides the following advan-
tages:
1. All possible matches (at a single point in the subject) are automat-
- ically found, and in particular, the longest match is found. To find
+ ically found, and in particular, the longest match is found. To find
more than one match using the standard algorithm, you have to do kludgy
things with callouts.
- 2. Because the alternative algorithm scans the subject string just
- once, and never needs to backtrack, it is possible to pass very long
- subject strings to the matching function in several pieces, checking
- for partial matching each time. Although it is possible to do multi-
- segment matching using the standard algorithm (pcre_exec()), by retain-
- ing partially matched substrings, it is more complicated. The pcrepar-
- tial documentation gives details of partial matching and discusses
- multi-segment matching.
+ 2. Because the alternative algorithm scans the subject string just
+ once, and never needs to backtrack (except for lookbehinds), it is pos-
+ sible to pass very long subject strings to the matching function in
+ several pieces, checking for partial matching each time. Although it is
+ possible to do multi-segment matching using the standard algorithm by
+ retaining partially matched substrings, it is more complicated. The
+ pcrepartial documentation gives details of partial matching and dis-
+ cusses multi-segment matching.
DISADVANTAGES OF THE ALTERNATIVE ALGORITHM
The alternative algorithm suffers from a number of disadvantages:
- 1. It is substantially slower than the standard algorithm. This is
- partly because it has to search for all possible matches, but is also
+ 1. It is substantially slower than the standard algorithm. This is
+ partly because it has to search for all possible matches, but is also
because it is less susceptible to optimization.
2. Capturing parentheses and back references are not supported.
@@ -801,8 +1064,8 @@
REVISION
- Last updated: 17 November 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 08 January 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
@@ -812,10 +1075,10 @@
NAME
PCRE - Perl-compatible regular expressions
+ #include
-PCRE NATIVE API
- #include
+PCRE NATIVE API BASIC FUNCTIONS
pcre *pcre_compile(const char *pattern, int options,
const char **errptr, int *erroffset,
@@ -829,6 +1092,8 @@
pcre_extra *pcre_study(const pcre *code, int options,
const char **errptr);
+ void pcre_free_study(pcre_extra *extra);
+
int pcre_exec(const pcre *code, const pcre_extra *extra,
const char *subject, int length, int startoffset,
int options, int *ovector, int ovecsize);
@@ -838,6 +1103,9 @@
int options, int *ovector, int ovecsize,
int *workspace, int wscount);
+
+PCRE NATIVE API STRING EXTRACTION FUNCTIONS
+
int pcre_copy_named_substring(const pcre *code,
const char *subject, int *ovector,
int stringcount, const char *stringname,
@@ -869,18 +1137,32 @@
void pcre_free_substring_list(const char **stringptr);
+
+PCRE NATIVE API AUXILIARY FUNCTIONS
+
+ pcre_jit_stack *pcre_jit_stack_alloc(int startsize, int maxsize);
+
+ void pcre_jit_stack_free(pcre_jit_stack *stack);
+
+ void pcre_assign_jit_stack(pcre_extra *extra,
+ pcre_jit_callback callback, void *data);
+
const unsigned char *pcre_maketables(void);
int pcre_fullinfo(const pcre *code, const pcre_extra *extra,
int what, void *where);
- int pcre_info(const pcre *code, int *optptr, int *firstcharptr);
-
int pcre_refcount(pcre *code, int adjust);
int pcre_config(int what, void *where);
- char *pcre_version(void);
+ const char *pcre_version(void);
+
+ int pcre_pattern_to_host_byte_order(pcre *code,
+ pcre_extra *extra, const unsigned char *tables);
+
+
+PCRE NATIVE API INDIRECTED FUNCTIONS
void *(*pcre_malloc)(size_t);
@@ -893,46 +1175,80 @@
int (*pcre_callout)(pcre_callout_block *);
+PCRE 8-BIT AND 16-BIT LIBRARIES
+
+ From release 8.30, PCRE can be compiled as a library for handling
+ 16-bit character strings as well as, or instead of, the original
+ library that handles 8-bit character strings. To avoid too much compli-
+ cation, this document describes the 8-bit versions of the functions,
+ with only occasional references to the 16-bit library.
+
+ The 16-bit functions operate in the same way as their 8-bit counter-
+ parts; they just use different data types for their arguments and
+ results, and their names start with pcre16_ instead of pcre_. For every
+ option that has UTF8 in its name (for example, PCRE_UTF8), there is a
+ corresponding 16-bit name with UTF8 replaced by UTF16. This facility is
+ in fact just cosmetic; the 16-bit option names define the same bit val-
+ ues.
+
+ References to bytes and UTF-8 in this document should be read as refer-
+ ences to 16-bit data quantities and UTF-16 when using the 16-bit
+ library, unless specified otherwise. More details of the specific dif-
+ ferences for the 16-bit library are given in the pcre16 page.
+
+
PCRE API OVERVIEW
PCRE has its own native API, which is described in this document. There
- are also some wrapper functions that correspond to the POSIX regular
- expression API. These are described in the pcreposix documentation.
- Both of these APIs define a set of C function calls. A C++ wrapper is
- distributed with PCRE. It is documented in the pcrecpp page.
-
- The native API C function prototypes are defined in the header file
- pcre.h, and on Unix systems the library itself is called libpcre. It
- can normally be accessed by adding -lpcre to the command for linking an
- application that uses PCRE. The header file defines the macros
- PCRE_MAJOR and PCRE_MINOR to contain the major and minor release num-
- bers for the library. Applications can use these to include support
+ are also some wrapper functions (for the 8-bit library only) that cor-
+ respond to the POSIX regular expression API, but they do not give
+ access to all the functionality. They are described in the pcreposix
+ documentation. Both of these APIs define a set of C function calls. A
+ C++ wrapper (again for the 8-bit library only) is also distributed with
+ PCRE. It is documented in the pcrecpp page.
+
+ The native API C function prototypes are defined in the header file
+ pcre.h, and on Unix-like systems the (8-bit) library itself is called
+ libpcre. It can normally be accessed by adding -lpcre to the command
+ for linking an application that uses PCRE. The header file defines the
+ macros PCRE_MAJOR and PCRE_MINOR to contain the major and minor release
+ numbers for the library. Applications can use these to include support
for different releases of PCRE.
In a Windows environment, if you want to statically link an application
- program against a non-dll pcre.a file, you must define PCRE_STATIC
- before including pcre.h or pcrecpp.h, because otherwise the pcre_mal-
+ program against a non-dll pcre.a file, you must define PCRE_STATIC
+ before including pcre.h or pcrecpp.h, because otherwise the pcre_mal-
loc() and pcre_free() exported functions will be declared
__declspec(dllimport), with unwanted results.
- The functions pcre_compile(), pcre_compile2(), pcre_study(), and
- pcre_exec() are used for compiling and matching regular expressions in
- a Perl-compatible manner. A sample program that demonstrates the sim-
- plest way of using them is provided in the file called pcredemo.c in
+ The functions pcre_compile(), pcre_compile2(), pcre_study(), and
+ pcre_exec() are used for compiling and matching regular expressions in
+ a Perl-compatible manner. A sample program that demonstrates the sim-
+ plest way of using them is provided in the file called pcredemo.c in
the PCRE source distribution. A listing of this program is given in the
- pcredemo documentation, and the pcresample documentation describes how
+ pcredemo documentation, and the pcresample documentation describes how
to compile and run it.
+ Just-in-time compiler support is an optional feature of PCRE that can
+ be built in appropriate hardware environments. It greatly speeds up the
+ matching performance of many patterns. Simple programs can easily
+ request that it be used if available, by setting an option that is
+ ignored when it is not relevant. More complicated programs might need
+ to make use of the functions pcre_jit_stack_alloc(),
+ pcre_jit_stack_free(), and pcre_assign_jit_stack() in order to control
+ the JIT code's memory usage. These functions are discussed in the
+ pcrejit documentation.
+
A second matching function, pcre_dfa_exec(), which is not Perl-compati-
- ble, is also provided. This uses a different algorithm for the match-
- ing. The alternative algorithm finds all possible matches (at a given
- point in the subject), and scans the subject just once (unless there
- are lookbehind assertions). However, this algorithm does not return
- captured substrings. A description of the two matching algorithms and
- their advantages and disadvantages is given in the pcrematching docu-
+ ble, is also provided. This uses a different algorithm for the match-
+ ing. The alternative algorithm finds all possible matches (at a given
+ point in the subject), and scans the subject just once (unless there
+ are lookbehind assertions). However, this algorithm does not return
+ captured substrings. A description of the two matching algorithms and
+ their advantages and disadvantages is given in the pcrematching docu-
mentation.
- In addition to the main compiling and matching functions, there are
+ In addition to the main compiling and matching functions, there are
convenience functions for extracting captured substrings from a subject
string that is matched by pcre_exec(). They are:
@@ -947,103 +1263,106 @@
pcre_free_substring() and pcre_free_substring_list() are also provided,
to free the memory used for extracted strings.
- The function pcre_maketables() is used to build a set of character
- tables in the current locale for passing to pcre_compile(),
- pcre_exec(), or pcre_dfa_exec(). This is an optional facility that is
- provided for specialist use. Most commonly, no special tables are
- passed, in which case internal tables that are generated when PCRE is
+ The function pcre_maketables() is used to build a set of character
+ tables in the current locale for passing to pcre_compile(),
+ pcre_exec(), or pcre_dfa_exec(). This is an optional facility that is
+ provided for specialist use. Most commonly, no special tables are
+ passed, in which case internal tables that are generated when PCRE is
built are used.
- The function pcre_fullinfo() is used to find out information about a
- compiled pattern; pcre_info() is an obsolete version that returns only
- some of the available information, but is retained for backwards com-
- patibility. The function pcre_version() returns a pointer to a string
- containing the version of PCRE and its date of release.
+ The function pcre_fullinfo() is used to find out information about a
+ compiled pattern. The function pcre_version() returns a pointer to a
+ string containing the version of PCRE and its date of release.
- The function pcre_refcount() maintains a reference count in a data
- block containing a compiled pattern. This is provided for the benefit
+ The function pcre_refcount() maintains a reference count in a data
+ block containing a compiled pattern. This is provided for the benefit
of object-oriented applications.
- The global variables pcre_malloc and pcre_free initially contain the
- entry points of the standard malloc() and free() functions, respec-
+ The global variables pcre_malloc and pcre_free initially contain the
+ entry points of the standard malloc() and free() functions, respec-
tively. PCRE calls the memory management functions via these variables,
- so a calling program can replace them if it wishes to intercept the
+ so a calling program can replace them if it wishes to intercept the
calls. This should be done before calling any PCRE functions.
- The global variables pcre_stack_malloc and pcre_stack_free are also
- indirections to memory management functions. These special functions
- are used only when PCRE is compiled to use the heap for remembering
+ The global variables pcre_stack_malloc and pcre_stack_free are also
+ indirections to memory management functions. These special functions
+ are used only when PCRE is compiled to use the heap for remembering
data, instead of recursive function calls, when running the pcre_exec()
- function. See the pcrebuild documentation for details of how to do
- this. It is a non-standard way of building PCRE, for use in environ-
- ments that have limited stacks. Because of the greater use of memory
- management, it runs more slowly. Separate functions are provided so
- that special-purpose external code can be used for this case. When
- used, these functions are always called in a stack-like manner (last
- obtained, first freed), and always for memory blocks of the same size.
- There is a discussion about PCRE's stack usage in the pcrestack docu-
+ function. See the pcrebuild documentation for details of how to do
+ this. It is a non-standard way of building PCRE, for use in environ-
+ ments that have limited stacks. Because of the greater use of memory
+ management, it runs more slowly. Separate functions are provided so
+ that special-purpose external code can be used for this case. When
+ used, these functions are always called in a stack-like manner (last
+ obtained, first freed), and always for memory blocks of the same size.
+ There is a discussion about PCRE's stack usage in the pcrestack docu-
mentation.
The global variable pcre_callout initially contains NULL. It can be set
- by the caller to a "callout" function, which PCRE will then call at
- specified points during a matching operation. Details are given in the
+ by the caller to a "callout" function, which PCRE will then call at
+ specified points during a matching operation. Details are given in the
pcrecallout documentation.
NEWLINES
- PCRE supports five different conventions for indicating line breaks in
- strings: a single CR (carriage return) character, a single LF (line-
+ PCRE supports five different conventions for indicating line breaks in
+ strings: a single CR (carriage return) character, a single LF (line-
feed) character, the two-character sequence CRLF, any of the three pre-
- ceding, or any Unicode newline sequence. The Unicode newline sequences
- are the three just mentioned, plus the single characters VT (vertical
- tab, U+000B), FF (formfeed, U+000C), NEL (next line, U+0085), LS (line
+ ceding, or any Unicode newline sequence. The Unicode newline sequences
+ are the three just mentioned, plus the single characters VT (vertical
+ tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line
separator, U+2028), and PS (paragraph separator, U+2029).
- Each of the first three conventions is used by at least one operating
- system as its standard newline sequence. When PCRE is built, a default
- can be specified. The default default is LF, which is the Unix stan-
- dard. When PCRE is run, the default can be overridden, either when a
+ Each of the first three conventions is used by at least one operating
+ system as its standard newline sequence. When PCRE is built, a default
+ can be specified. The default default is LF, which is the Unix stan-
+ dard. When PCRE is run, the default can be overridden, either when a
pattern is compiled, or when it is matched.
At compile time, the newline convention can be specified by the options
- argument of pcre_compile(), or it can be specified by special text at
+ argument of pcre_compile(), or it can be specified by special text at
the start of the pattern itself; this overrides any other settings. See
the pcrepattern page for details of the special character sequences.
In the PCRE documentation the word "newline" is used to mean "the char-
- acter or pair of characters that indicate a line break". The choice of
- newline convention affects the handling of the dot, circumflex, and
+ acter or pair of characters that indicate a line break". The choice of
+ newline convention affects the handling of the dot, circumflex, and
dollar metacharacters, the handling of #-comments in /x mode, and, when
- CRLF is a recognized line ending sequence, the match position advance-
+ CRLF is a recognized line ending sequence, the match position advance-
ment for a non-anchored pattern. There is more detail about this in the
section on pcre_exec() options below.
- The choice of newline convention does not affect the interpretation of
- the \n or \r escape sequences, nor does it affect what \R matches,
+ The choice of newline convention does not affect the interpretation of
+ the \n or \r escape sequences, nor does it affect what \R matches,
which is controlled in a similar way, but by separate options.
MULTITHREADING
- The PCRE functions can be used in multi-threading applications, with
+ The PCRE functions can be used in multi-threading applications, with
the proviso that the memory management functions pointed to by
pcre_malloc, pcre_free, pcre_stack_malloc, and pcre_stack_free, and the
callout function pointed to by pcre_callout, are shared by all threads.
- The compiled form of a regular expression is not altered during match-
+ The compiled form of a regular expression is not altered during match-
ing, so the same compiled pattern can safely be used by several threads
at once.
+ If the just-in-time optimization feature is being used, it needs sepa-
+ rate memory stack areas for each thread. See the pcrejit documentation
+ for more details.
+
SAVING PRECOMPILED PATTERNS FOR LATER USE
The compiled form of a regular expression can be saved and re-used at a
- later time, possibly by a different program, and even on a host other
- than the one on which it was compiled. Details are given in the
- pcreprecompile documentation. However, compiling a regular expression
- with one version of PCRE for use with a different version is not guar-
- anteed to work and may cause crashes.
+ later time, possibly by a different program, and even on a host other
+ than the one on which it was compiled. Details are given in the
+ pcreprecompile documentation, which includes a description of the
+ pcre_pattern_to_host_byte_order() function. However, compiling a regu-
+ lar expression with one version of PCRE for use with a different ver-
+ sion is not guaranteed to work and may cause crashes.
CHECKING BUILD-TIME OPTIONS
@@ -1057,72 +1376,99 @@
The first argument for pcre_config() is an integer, specifying which
information is required; the second argument is a pointer to a variable
- into which the information is placed. The following information is
+ into which the information is placed. The returned value is zero on
+ success, or the negative error code PCRE_ERROR_BADOPTION if the value
+ in the first argument is not recognized. The following information is
available:
PCRE_CONFIG_UTF8
The output is an integer that is set to one if UTF-8 support is avail-
- able; otherwise it is set to zero.
+ able; otherwise it is set to zero. If this option is given to the
+ 16-bit version of this function, pcre16_config(), the result is
+ PCRE_ERROR_BADOPTION.
+
+ PCRE_CONFIG_UTF16
+
+ The output is an integer that is set to one if UTF-16 support is avail-
+ able; otherwise it is set to zero. This value should normally be given
+ to the 16-bit version of this function, pcre16_config(). If it is given
+ to the 8-bit version of this function, the result is PCRE_ERROR_BADOP-
+ TION.
PCRE_CONFIG_UNICODE_PROPERTIES
The output is an integer that is set to one if support for Unicode
character properties is available; otherwise it is set to zero.
+ PCRE_CONFIG_JIT
+
+ The output is an integer that is set to one if support for just-in-time
+ compiling is available; otherwise it is set to zero.
+
+ PCRE_CONFIG_JITTARGET
+
+ The output is a pointer to a zero-terminated "const char *" string. If
+ JIT support is available, the string contains the name of the architec-
+ ture for which the JIT compiler is configured, for example "x86 32bit
+ (little endian + unaligned)". If JIT support is not available, the
+ result is NULL.
+
PCRE_CONFIG_NEWLINE
- The output is an integer whose value specifies the default character
- sequence that is recognized as meaning "newline". The four values that
+ The output is an integer whose value specifies the default character
+ sequence that is recognized as meaning "newline". The four values that
are supported are: 10 for LF, 13 for CR, 3338 for CRLF, -2 for ANYCRLF,
- and -1 for ANY. Though they are derived from ASCII, the same values
+ and -1 for ANY. Though they are derived from ASCII, the same values
are returned in EBCDIC environments. The default should normally corre-
spond to the standard sequence for your operating system.
PCRE_CONFIG_BSR
The output is an integer whose value indicates what character sequences
- the \R escape sequence matches by default. A value of 0 means that \R
- matches any Unicode line ending sequence; a value of 1 means that \R
+ the \R escape sequence matches by default. A value of 0 means that \R
+ matches any Unicode line ending sequence; a value of 1 means that \R
matches only CR, LF, or CRLF. The default can be overridden when a pat-
tern is compiled or matched.
PCRE_CONFIG_LINK_SIZE
- The output is an integer that contains the number of bytes used for
- internal linkage in compiled regular expressions. The value is 2, 3, or
- 4. Larger values allow larger regular expressions to be compiled, at
- the expense of slower matching. The default value of 2 is sufficient
- for all but the most massive patterns, since it allows the compiled
- pattern to be up to 64K in size.
+ The output is an integer that contains the number of bytes used for
+ internal linkage in compiled regular expressions. For the 8-bit
+ library, the value can be 2, 3, or 4. For the 16-bit library, the value
+ is either 2 or 4 and is still a number of bytes. The default value of 2
+ is sufficient for all but the most massive patterns, since it allows
+ the compiled pattern to be up to 64K in size. Larger values allow
+ larger regular expressions to be compiled, at the expense of slower
+ matching.
PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
- The output is an integer that contains the threshold above which the
- POSIX interface uses malloc() for output vectors. Further details are
+ The output is an integer that contains the threshold above which the
+ POSIX interface uses malloc() for output vectors. Further details are
given in the pcreposix documentation.
PCRE_CONFIG_MATCH_LIMIT
- The output is a long integer that gives the default limit for the num-
- ber of internal matching function calls in a pcre_exec() execution.
+ The output is a long integer that gives the default limit for the num-
+ ber of internal matching function calls in a pcre_exec() execution.
Further details are given with pcre_exec() below.
PCRE_CONFIG_MATCH_LIMIT_RECURSION
The output is a long integer that gives the default limit for the depth
- of recursion when calling the internal matching function in a
- pcre_exec() execution. Further details are given with pcre_exec()
+ of recursion when calling the internal matching function in a
+ pcre_exec() execution. Further details are given with pcre_exec()
below.
PCRE_CONFIG_STACKRECURSE
- The output is an integer that is set to one if internal recursion when
+ The output is an integer that is set to one if internal recursion when
running pcre_exec() is implemented by recursive function calls that use
- the stack to remember their state. This is the usual way that PCRE is
+ the stack to remember their state. This is the usual way that PCRE is
compiled. The output is zero if PCRE was compiled to use blocks of data
- on the heap instead of recursive function calls. In this case,
- pcre_stack_malloc and pcre_stack_free are called to manage memory
+ on the heap instead of recursive function calls. In this case,
+ pcre_stack_malloc and pcre_stack_free are called to manage memory
blocks on the heap, thus avoiding the use of the stack.
@@ -1139,65 +1485,65 @@
Either of the functions pcre_compile() or pcre_compile2() can be called
to compile a pattern into an internal form. The only difference between
- the two interfaces is that pcre_compile2() has an additional argument,
- errorcodeptr, via which a numerical error code can be returned. To
- avoid too much repetition, we refer just to pcre_compile() below, but
+ the two interfaces is that pcre_compile2() has an additional argument,
+ errorcodeptr, via which a numerical error code can be returned. To
+ avoid too much repetition, we refer just to pcre_compile() below, but
the information applies equally to pcre_compile2().
The pattern is a C string terminated by a binary zero, and is passed in
- the pattern argument. A pointer to a single block of memory that is
- obtained via pcre_malloc is returned. This contains the compiled code
+ the pattern argument. A pointer to a single block of memory that is
+ obtained via pcre_malloc is returned. This contains the compiled code
and related data. The pcre type is defined for the returned block; this
is a typedef for a structure whose contents are not externally defined.
It is up to the caller to free the memory (via pcre_free) when it is no
longer required.
- Although the compiled code of a PCRE regex is relocatable, that is, it
+ Although the compiled code of a PCRE regex is relocatable, that is, it
does not depend on memory location, the complete pcre data block is not
- fully relocatable, because it may contain a copy of the tableptr argu-
+ fully relocatable, because it may contain a copy of the tableptr argu-
ment, which is an address (see below).
The options argument contains various bit settings that affect the com-
- pilation. 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
- pcrepattern documentation). For those options that can be different in
- different parts of the pattern, the contents of the options argument
+ pilation. 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
+ pcrepattern documentation). For those options that can be different in
+ different parts of the pattern, the contents of the options argument
specifies their settings at the start of compilation and execution. The
- PCRE_ANCHORED, PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and
- PCRE_NO_START_OPT options can be set at the time of matching as well as
- at compile time.
+ PCRE_ANCHORED, PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and
+ PCRE_NO_START_OPTIMIZE options can be set at the time of matching as
+ well as at compile time.
If errptr is NULL, pcre_compile() returns NULL immediately. Otherwise,
- if compilation of a pattern fails, pcre_compile() returns NULL, and
+ if compilation of a pattern fails, pcre_compile() returns NULL, and
sets the variable pointed to by errptr to point to a textual error mes-
sage. This is a static string that is part of the library. You must not
- try to free it. The offset from the start of the pattern to the byte
- that was being processed when the error was discovered is placed in the
- variable pointed to by erroffset, which must not be NULL. If it is, an
- immediate error is given. Some errors are not detected until checks are
- carried out when the whole pattern has been scanned; in this case the
- offset is set to the end of the pattern.
+ try to free it. Normally, the offset from the start of the pattern to
+ the byte that was being processed when the error was discovered is
+ placed in the variable pointed to by erroffset, which must not be NULL
+ (if it is, an immediate error is given). However, for an invalid UTF-8
+ string, the offset is that of the first byte of the failing character.
+ Some errors are not detected until the whole pattern has been scanned;
+ in these cases, the offset passed back is the length of the pattern.
Note that the offset is in bytes, not characters, even in UTF-8 mode.
- It may point into the middle of a UTF-8 character (for example, when
- PCRE_ERROR_BADUTF8 is returned for an invalid UTF-8 string).
+ It may sometimes point into the middle of a UTF-8 character.
- If pcre_compile2() is used instead of pcre_compile(), and the error-
- codeptr argument is not NULL, a non-zero error code number is returned
- via this argument in the event of an error. This is in addition to the
+ If pcre_compile2() is used instead of pcre_compile(), and the error-
+ codeptr argument is not NULL, a non-zero error code number is returned
+ via this argument in the event of an error. This is in addition to the
textual error message. Error codes and messages are listed below.
- If the final argument, tableptr, is NULL, PCRE uses a default set of
- character tables that are built when PCRE is compiled, using the
- default C locale. Otherwise, tableptr must be an address that is the
- result of a call to pcre_maketables(). This value is stored with the
- compiled pattern, and used again by pcre_exec(), unless another table
+ If the final argument, tableptr, is NULL, PCRE uses a default set of
+ character tables that are built when PCRE is compiled, using the
+ default C locale. Otherwise, tableptr must be an address that is the
+ result of a call to pcre_maketables(). This value is stored with the
+ compiled pattern, and used again by pcre_exec(), unless another table
pointer is passed to it. For more discussion, see the section on locale
support below.
- This code fragment shows a typical straightforward call to pcre_com-
+ This code fragment shows a typical straightforward call to pcre_com-
pile():
pcre *re;
@@ -1210,147 +1556,161 @@
&erroffset, /* for error offset */
NULL); /* use default character tables */
- The following names for option bits are defined in the pcre.h header
+ The following names for option bits are defined in the pcre.h header
file:
PCRE_ANCHORED
If this bit is set, the pattern is forced to be "anchored", that is, it
- is constrained to match only at the first matching point in the string
- that is being searched (the "subject string"). This effect can also be
- achieved by appropriate constructs in the pattern itself, which is the
+ is constrained to match only at the first matching point in the string
+ that is being searched (the "subject string"). This effect can also be
+ achieved by appropriate constructs in the pattern itself, which is the
only way to do it in Perl.
PCRE_AUTO_CALLOUT
If this bit is set, pcre_compile() automatically inserts callout items,
- all with number 255, before each pattern item. For discussion of the
+ all with number 255, before each pattern item. For discussion of the
callout facility, see the pcrecallout documentation.
PCRE_BSR_ANYCRLF
PCRE_BSR_UNICODE
These options (which are mutually exclusive) control what the \R escape
- sequence matches. The choice is either to match only CR, LF, or CRLF,
+ sequence matches. The choice is either to match only CR, LF, or CRLF,
or to match any Unicode newline sequence. The default is specified when
PCRE is built. It can be overridden from within the pattern, or by set-
ting an option when a compiled pattern is matched.
PCRE_CASELESS
- If this bit is set, letters in the pattern match both upper and lower
- case letters. It is equivalent to Perl's /i option, and it can be
- changed within a pattern by a (?i) option setting. In UTF-8 mode, PCRE
- always understands the concept of case for characters whose values are
- less than 128, so caseless matching is always possible. For characters
- with higher values, the concept of case is supported if PCRE is com-
- piled with Unicode property support, but not otherwise. If you want to
- use caseless matching for characters 128 and above, you must ensure
- that PCRE is compiled with Unicode property support as well as with
+ If this bit is set, letters in the pattern match both upper and lower
+ case letters. It is equivalent to Perl's /i option, and it can be
+ changed within a pattern by a (?i) option setting. In UTF-8 mode, PCRE
+ always understands the concept of case for characters whose values are
+ less than 128, so caseless matching is always possible. For characters
+ with higher values, the concept of case is supported if PCRE is com-
+ piled with Unicode property support, but not otherwise. If you want to
+ use caseless matching for characters 128 and above, you must ensure
+ that PCRE is compiled with Unicode property support as well as with
UTF-8 support.
PCRE_DOLLAR_ENDONLY
- If this bit is set, a dollar metacharacter in the pattern matches only
- at the end of the subject string. Without this option, a dollar also
- matches immediately before a newline at the end of the string (but not
- before any other newlines). The PCRE_DOLLAR_ENDONLY option is ignored
- if PCRE_MULTILINE is set. There is no equivalent to this option in
+ If this bit is set, a dollar metacharacter in the pattern matches only
+ at the end of the subject string. Without this option, a dollar also
+ matches immediately before a newline at the end of the string (but not
+ before any other newlines). The PCRE_DOLLAR_ENDONLY option is ignored
+ if PCRE_MULTILINE is set. There is no equivalent to this option in
Perl, and no way to set it within a pattern.
PCRE_DOTALL
- If this bit is set, a dot metacharacter in the pattern matches a char-
+ If this bit is set, a dot metacharacter in the pattern matches a char-
acter of any value, including one that indicates a newline. However, it
- only ever matches one character, even if newlines are coded as CRLF.
- Without this option, a dot does not match when the current position is
+ only ever matches one character, even if newlines are coded as CRLF.
+ Without this option, a dot does not match when the current position is
at a newline. This option is equivalent to Perl's /s option, and it can
- be changed within a pattern by a (?s) option setting. A negative class
+ be changed within a pattern by a (?s) option setting. A negative class
such as [^a] always matches newline characters, independent of the set-
ting of this option.
PCRE_DUPNAMES
- If this bit is set, names used to identify capturing subpatterns need
+ If this bit is set, names used to identify capturing subpatterns need
not be unique. This can be helpful for certain types of pattern when it
- is known that only one instance of the named subpattern can ever be
- matched. There are more details of named subpatterns below; see also
+ is known that only one instance of the named subpattern can ever be
+ matched. There are more details of named subpatterns below; see also
the pcrepattern documentation.
PCRE_EXTENDED
- If this bit is set, whitespace data characters in the pattern are
- totally ignored except when escaped or inside a character class. White-
+ If this bit is set, white space data characters in the pattern are
+ totally ignored except when escaped or inside a character class. White
space does not include the VT character (code 11). In addition, charac-
ters between an unescaped # outside a character class and the next new-
- line, inclusive, are also ignored. This is equivalent to Perl's /x
- option, and it can be changed within a pattern by a (?x) option set-
+ line, inclusive, are also ignored. This is equivalent to Perl's /x
+ option, and it can be changed within a pattern by a (?x) option set-
ting.
- Which characters are interpreted as newlines is controlled by the
- options passed to pcre_compile() or by a special sequence at the start
- of the pattern, as described in the section entitled "Newline conven-
+ Which characters are interpreted as newlines is controlled by the
+ options passed to pcre_compile() or by a special sequence at the start
+ of the pattern, as described in the section entitled "Newline conven-
tions" in the pcrepattern documentation. Note that the end of this type
- of comment is a literal newline sequence in the pattern; escape
+ of comment is a literal newline sequence in the pattern; escape
sequences that happen to represent a newline do not count.
- This option makes it possible to include comments inside complicated
- patterns. Note, however, that this applies only to data characters.
- Whitespace characters may never appear within special character
+ This option makes it possible to include comments inside complicated
+ patterns. Note, however, that this applies only to data characters.
+ White space characters may never appear within special character
sequences in a pattern, for example within the sequence (?( that intro-
duces a conditional subpattern.
PCRE_EXTRA
- This option was invented in order to turn on additional functionality
- of PCRE that is incompatible with Perl, but it is currently of very
- little use. When set, any backslash in a pattern that is followed by a
- letter that has no special meaning causes an error, thus reserving
- these combinations for future expansion. By default, as in Perl, a
- backslash followed by a letter with no special meaning is treated as a
+ This option was invented in order to turn on additional functionality
+ of PCRE that is incompatible with Perl, but it is currently of very
+ little use. When set, any backslash in a pattern that is followed by a
+ letter that has no special meaning causes an error, thus reserving
+ these combinations for future expansion. By default, as in Perl, a
+ backslash followed by a letter with no special meaning is treated as a
literal. (Perl can, however, be persuaded to give an error for this, by
- running it with the -w option.) There are at present no other features
- controlled by this option. It can also be set by a (?X) option setting
+ running it with the -w option.) There are at present no other features
+ controlled by this option. It can also be set by a (?X) option setting
within a pattern.
PCRE_FIRSTLINE
- If this option is set, an unanchored pattern is required to match
- before or at the first newline in the subject string, though the
+ If this option is set, an unanchored pattern is required to match
+ before or at the first newline in the subject string, though the
matched text may continue over the newline.
PCRE_JAVASCRIPT_COMPAT
If this option is set, PCRE's behaviour is changed in some ways so that
- it is compatible with JavaScript rather than Perl. The changes are as
+ it is compatible with JavaScript rather than Perl. The changes are as
follows:
- (1) A lone closing square bracket in a pattern causes a compile-time
- error, because this is illegal in JavaScript (by default it is treated
+ (1) A lone closing square bracket in a pattern causes a compile-time
+ error, because this is illegal in JavaScript (by default it is treated
as a data character). Thus, the pattern AB]CD becomes illegal when this
option is set.
- (2) At run time, a back reference to an unset subpattern group matches
- an empty string (by default this causes the current matching alterna-
- tive to fail). A pattern such as (\1)(a) succeeds when this option is
- set (assuming it can find an "a" in the subject), whereas it fails by
+ (2) At run time, a back reference to an unset subpattern group matches
+ an empty string (by default this causes the current matching alterna-
+ tive to fail). A pattern such as (\1)(a) succeeds when this option is
+ set (assuming it can find an "a" in the subject), whereas it fails by
default, for Perl compatibility.
+ (3) \U matches an upper case "U" character; by default \U causes a com-
+ pile time error (Perl uses \U to upper case subsequent characters).
+
+ (4) \u matches a lower case "u" character unless it is followed by four
+ hexadecimal digits, in which case the hexadecimal number defines the
+ code point to match. By default, \u causes a compile time error (Perl
+ uses it to upper case the following character).
+
+ (5) \x matches a lower case "x" character unless it is followed by two
+ hexadecimal digits, in which case the hexadecimal number defines the
+ code point to match. By default, as in Perl, a hexadecimal number is
+ always expected after \x, but it may have zero, one, or two digits (so,
+ for example, \xz matches a binary zero character followed by z).
+
PCRE_MULTILINE
- By default, PCRE treats the subject string as consisting of a single
- line of characters (even if it actually contains newlines). The "start
- of line" metacharacter (^) matches only at the start of the string,
- while the "end of line" metacharacter ($) matches only at the end of
+ By default, PCRE treats the subject string as consisting of a single
+ line of characters (even if it actually contains newlines). The "start
+ of line" metacharacter (^) matches only at the start of the string,
+ while the "end of line" metacharacter ($) matches only at the end of
the string, or before a terminating newline (unless PCRE_DOLLAR_ENDONLY
is set). This is the same as Perl.
- When PCRE_MULTILINE it is set, the "start of line" and "end of line"
- constructs match immediately following or immediately before internal
- newlines in the subject string, respectively, as well as at the very
- start and end. This is equivalent to Perl's /m option, and it can be
+ When PCRE_MULTILINE it is set, the "start of line" and "end of line"
+ constructs match immediately following or immediately before internal
+ newlines in the subject string, respectively, as well as at the very
+ start and end. This is equivalent to Perl's /m option, and it can be
changed within a pattern by a (?m) option setting. If there are no new-
- lines in a subject string, or no occurrences of ^ or $ in a pattern,
+ lines in a subject string, or no occurrences of ^ or $ in a pattern,
setting PCRE_MULTILINE has no effect.
PCRE_NEWLINE_CR
@@ -1359,32 +1719,32 @@
PCRE_NEWLINE_ANYCRLF
PCRE_NEWLINE_ANY
- These options override the default newline definition that was chosen
- when PCRE was built. Setting the first or the second specifies that a
- newline is indicated by a single character (CR or LF, respectively).
- Setting PCRE_NEWLINE_CRLF specifies that a newline is indicated by the
- two-character CRLF sequence. Setting PCRE_NEWLINE_ANYCRLF specifies
+ These options override the default newline definition that was chosen
+ when PCRE was built. Setting the first or the second specifies that a
+ newline is indicated by a single character (CR or LF, respectively).
+ Setting PCRE_NEWLINE_CRLF specifies that a newline is indicated by the
+ two-character CRLF sequence. Setting PCRE_NEWLINE_ANYCRLF specifies
that any of the three preceding sequences should be recognized. Setting
- PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be
+ PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be
recognized. The Unicode newline sequences are the three just mentioned,
- plus the single characters VT (vertical tab, U+000B), FF (formfeed,
- U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS
- (paragraph separator, U+2029). The last two are recognized only in
- UTF-8 mode.
+ plus the single characters VT (vertical tab, U+000B), FF (form feed,
+ U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS
+ (paragraph separator, U+2029). For the 8-bit library, the last two are
+ recognized only in UTF-8 mode.
- The newline setting in the options word uses three bits that are
+ The newline setting in the options word uses three bits that are
treated as a number, giving eight possibilities. Currently only six are
- used (default plus the five values above). This means that if you set
- more than one newline option, the combination may or may not be sensi-
+ used (default plus the five values above). This means that if you set
+ more than one newline option, the combination may or may not be sensi-
ble. For example, PCRE_NEWLINE_CR with PCRE_NEWLINE_LF is equivalent to
- PCRE_NEWLINE_CRLF, but other combinations may yield unused numbers and
+ PCRE_NEWLINE_CRLF, but other combinations may yield unused numbers and
cause an error.
- The only time that a line break in a pattern is specially recognized
- when compiling is when PCRE_EXTENDED is set. CR and LF are whitespace
- characters, and so are ignored in this mode. Also, an unescaped # out-
- side a character class indicates a comment that lasts until after the
- next line break sequence. In other circumstances, line break sequences
+ The only time that a line break in a pattern is specially recognized
+ when compiling is when PCRE_EXTENDED is set. CR and LF are white space
+ characters, and so are ignored in this mode. Also, an unescaped # out-
+ side a character class indicates a comment that lasts until after the
+ next line break sequence. In other circumstances, line break sequences
in patterns are treated as literal data.
The newline option that is set at compile time becomes the default that
@@ -1393,66 +1753,67 @@
PCRE_NO_AUTO_CAPTURE
If this option is set, it disables the use of numbered capturing paren-
- theses in the pattern. Any opening parenthesis that is not followed by
- ? behaves as if it were followed by ?: but named parentheses can still
- be used for capturing (and they acquire numbers in the usual way).
+ theses in the pattern. Any opening parenthesis that is not followed by
+ ? behaves as if it were followed by ?: but named parentheses can still
+ be used for capturing (and they acquire numbers in the usual way).
There is no equivalent of this option in Perl.
NO_START_OPTIMIZE
- This is an option that acts at matching time; that is, it is really an
- option for pcre_exec() or pcre_dfa_exec(). If it is set at compile
- time, it is remembered with the compiled pattern and assumed at match-
- ing time. For details see the discussion of PCRE_NO_START_OPTIMIZE
+ This is an option that acts at matching time; that is, it is really an
+ option for pcre_exec() or pcre_dfa_exec(). If it is set at compile
+ time, it is remembered with the compiled pattern and assumed at match-
+ ing time. For details see the discussion of PCRE_NO_START_OPTIMIZE
below.
PCRE_UCP
- This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W,
- \w, and some of the POSIX character classes. By default, only ASCII
- characters are recognized, but if PCRE_UCP is set, Unicode properties
- are used instead to classify characters. More details are given in the
- section on generic character types in the pcrepattern page. If you set
- PCRE_UCP, matching one of the items it affects takes much longer. The
- option is available only if PCRE has been compiled with Unicode prop-
+ This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W,
+ \w, and some of the POSIX character classes. By default, only ASCII
+ characters are recognized, but if PCRE_UCP is set, Unicode properties
+ are used instead to classify characters. More details are given in the
+ section on generic character types in the pcrepattern page. If you set
+ PCRE_UCP, matching one of the items it affects takes much longer. The
+ option is available only if PCRE has been compiled with Unicode prop-
erty support.
PCRE_UNGREEDY
- This option inverts the "greediness" of the quantifiers so that they
- are not greedy by default, but become greedy if followed by "?". It is
- not compatible with Perl. It can also be set by a (?U) option setting
+ This option inverts the "greediness" of the quantifiers so that they
+ are not greedy by default, but become greedy if followed by "?". It is
+ not compatible with Perl. It can also be set by a (?U) option setting
within the pattern.
PCRE_UTF8
- This option causes PCRE to regard both the pattern and the subject as
- strings of UTF-8 characters instead of single-byte character strings.
- However, it is available only when PCRE is built to include UTF-8 sup-
- port. If not, the use of this option provokes an error. Details of how
- this option changes the behaviour of PCRE are given in the section on
- UTF-8 support in the main pcre page.
+ This option causes PCRE to regard both the pattern and the subject as
+ strings of UTF-8 characters instead of single-byte strings. However, it
+ is available only when PCRE is built to include UTF support. If not,
+ the use of this option provokes an error. Details of how this option
+ changes the behaviour of PCRE are given in the pcreunicode page.
PCRE_NO_UTF8_CHECK
When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is
automatically checked. There is a discussion about the validity of
- UTF-8 strings in the main pcre page. If an invalid UTF-8 sequence of
- bytes is found, pcre_compile() returns an error. If you already know
- that your pattern is valid, and you want to skip this check for perfor-
- mance reasons, you can set the PCRE_NO_UTF8_CHECK option. When it is
- set, the effect of passing an invalid UTF-8 string as a pattern is
- undefined. It may cause your program to crash. Note that this option
- can also be passed to pcre_exec() and pcre_dfa_exec(), to suppress the
- UTF-8 validity checking of subject strings.
+ UTF-8 strings in the pcreunicode page. If an invalid UTF-8 sequence is
+ found, pcre_compile() returns an error. If you already know that your
+ pattern is valid, and you want to skip this check for performance rea-
+ sons, you can set the PCRE_NO_UTF8_CHECK option. When it is set, the
+ effect of passing an invalid UTF-8 string as a pattern is undefined. It
+ may cause your program to crash. Note that this option can also be
+ passed to pcre_exec() and pcre_dfa_exec(), to suppress the validity
+ checking of subject strings.
COMPILATION ERROR CODES
The following table lists the error codes than may be returned by
pcre_compile2(), along with the error messages that may be returned by
- both compiling functions. As PCRE has developed, some error codes have
- fallen out of use. To avoid confusion, they have not been re-used.
+ both compiling functions. Note that error messages are always 8-bit
+ ASCII strings, even in 16-bit mode. As PCRE has developed, some error
+ codes have fallen out of use. To avoid confusion, they have not been
+ re-used.
0 no error
1 \ at end of pattern
@@ -1486,26 +1847,26 @@
29 (?R or (?[+-]digits must be followed by )
30 unknown POSIX class name
31 POSIX collating elements are not supported
- 32 this version of PCRE is not compiled with PCRE_UTF8 support
+ 32 this version of PCRE is compiled without UTF support
33 [this code is not in use]
34 character value in \x{...} sequence is too large
35 invalid condition (?(0)
36 \C not allowed in lookbehind assertion
- 37 PCRE does not support \L, \l, \N, \U, or \u
+ 37 PCRE does not support \L, \l, \N{name}, \U, or \u
38 number after (?C is > 255
39 closing ) for (?C expected
40 recursive call could loop indefinitely
41 unrecognized character after (?P
42 syntax error in subpattern name (missing terminator)
43 two named subpatterns have the same name
- 44 invalid UTF-8 string
+ 44 invalid UTF-8 string (specifically UTF-8)
45 support for \P, \p, and \X has not been compiled
46 malformed \P or \p sequence
47 unknown property name after \P or \p
48 subpattern name is too long (maximum 32 characters)
49 too many named subpatterns (maximum 10000)
50 [this code is not in use]
- 51 octal value is greater than \377 (not in UTF-8 mode)
+ 51 octal value is greater than \377 in 8-bit non-UTF-8 mode
52 internal error: overran compiling workspace
53 internal error: previously-checked referenced subpattern
not found
@@ -1524,7 +1885,17 @@
65 different names for subpatterns of the same number are
not allowed
66 (*MARK) must have an argument
- 67 this version of PCRE is not compiled with PCRE_UCP support
+ 67 this version of PCRE is not compiled with Unicode property
+ support
+ 68 \c must be followed by an ASCII character
+ 69 \k is not followed by a braced, angle-bracketed, or quoted name
+ 70 internal error: unknown opcode in find_fixedlength()
+ 71 \N is not supported in a class
+ 72 too many forward references
+ 73 disallowed Unicode code point (>= 0xd800 && <= 0xdfff)
+ 74 invalid UTF-16 string (specifically UTF-16)
+ 75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
+ 76 character value in \u.... sequence is too large
The numbers 32 and 10000 in errors 48 and 49 are defaults; different
values may be used if the limits were changed when PCRE was built.
@@ -1553,8 +1924,26 @@
wants to pass any of the other fields to pcre_exec() or
pcre_dfa_exec(), it must set up its own pcre_extra block.
- The second argument of pcre_study() contains option bits. At present,
- no options are defined, and this argument should always be zero.
+ The second argument of pcre_study() contains option bits. There are
+ three options:
+
+ PCRE_STUDY_JIT_COMPILE
+ PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
+ PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
+
+ If any of these are set, and the just-in-time compiler is available,
+ the pattern is further compiled into machine code that executes much
+ faster than the pcre_exec() interpretive matching function. If the
+ just-in-time compiler is not available, these options are ignored. All
+ other bits in the options argument must be zero.
+
+ JIT compilation is a heavyweight optimization. It can take some time
+ for patterns to be analyzed, and for one-off matches and simple pat-
+ terns the benefit of faster execution might be offset by a much slower
+ study time. Not all patterns can be optimized by the JIT compiler. For
+ those that cannot be handled, matching automatically falls back to the
+ pcre_exec() interpreter. For more details, see the pcrejit documenta-
+ tion.
The third argument for pcre_study() is a pointer for an error message.
If studying succeeds (even if no data is returned), the variable it
@@ -1563,13 +1952,29 @@
must not try to free it. You should test the error pointer for NULL
after calling pcre_study(), to be sure that it has run successfully.
- This is a typical call to pcre_study():
+ When you are finished with a pattern, you can free the memory used for
+ the study data by calling pcre_free_study(). This function was added to
+ the API for release 8.20. For earlier versions, the memory could be
+ freed with pcre_free(), just like the pattern itself. This will still
+ work in cases where JIT optimization is not used, but it is advisable
+ to change to the new function when convenient.
- pcre_extra *pe;
- pe = pcre_study(
+ This is a typical way in which pcre_study() is used (except that in a
+ real application there should be tests for errors):
+
+ int rc;
+ pcre *re;
+ pcre_extra *sd;
+ re = pcre_compile("pattern", 0, &error, &erroroffset, NULL);
+ sd = pcre_study(
re, /* result of pcre_compile() */
- 0, /* no options exist */
+ 0, /* no options */
&error); /* set to NULL or points to a message */
+ rc = pcre_exec( /* see below for details of pcre_exec() options */
+ re, sd, "subject", 7, 0, 0, ovector, 30);
+ ...
+ pcre_free_study(sd);
+ pcre_free(re);
Studying a pattern does two things: first, a lower bound for the length
of subject string that is needed to match the pattern is computed. This
@@ -1582,70 +1987,73 @@
Studying a pattern is also useful for non-anchored patterns that do not
have a single fixed starting character. A bitmap of possible starting
bytes is created. This speeds up finding a position in the subject at
- which to start matching.
+ which to start matching. (In 16-bit mode, the bitmap is used for 16-bit
+ values less than 256.)
- The two optimizations just described can be disabled by setting the
- PCRE_NO_START_OPTIMIZE option when calling pcre_exec() or
- pcre_dfa_exec(). You might want to do this if your pattern contains
- callouts or (*MARK), and you want to make use of these facilities in
- cases where matching fails. See the discussion of PCRE_NO_START_OPTI-
- MIZE below.
+ These two optimizations apply to both pcre_exec() and pcre_dfa_exec(),
+ and the information is also used by the JIT compiler. The optimiza-
+ tions can be disabled by setting the PCRE_NO_START_OPTIMIZE option when
+ calling pcre_exec() or pcre_dfa_exec(), but if this is done, JIT execu-
+ tion is also disabled. You might want to do this if your pattern con-
+ tains callouts or (*MARK) and you want to make use of these facilities
+ in cases where matching fails. See the discussion of
+ PCRE_NO_START_OPTIMIZE below.
LOCALE SUPPORT
- PCRE handles caseless matching, and determines whether characters are
- letters, digits, or whatever, by reference to a set of tables, indexed
- by character value. When running in UTF-8 mode, this applies only to
- characters with codes less than 128. By default, higher-valued codes
+ PCRE handles caseless matching, and determines whether characters are
+ letters, digits, or whatever, by reference to a set of tables, indexed
+ by character value. When running in UTF-8 mode, this applies only to
+ characters with codes less than 128. By default, higher-valued codes
never match escapes such as \w or \d, but they can be tested with \p if
- PCRE is built with Unicode character property support. Alternatively,
- the PCRE_UCP option can be set at compile time; this causes \w and
+ PCRE is built with Unicode character property support. Alternatively,
+ the PCRE_UCP option can be set at compile time; this causes \w and
friends to use Unicode property support instead of built-in tables. The
use of locales with Unicode is discouraged. If you are handling charac-
- ters with codes greater than 128, you should either use UTF-8 and Uni-
+ ters with codes greater than 128, you should either use UTF-8 and Uni-
code, or use locales, but not try to mix the two.
- PCRE contains an internal set of tables that are used when the final
- argument of pcre_compile() is NULL. These are sufficient for many
+ PCRE contains an internal set of tables that are used when the final
+ argument of pcre_compile() is NULL. These are sufficient for many
applications. Normally, the internal tables recognize only ASCII char-
acters. However, when PCRE is built, it is possible to cause the inter-
nal tables to be rebuilt in the default "C" locale of the local system,
which may cause them to be different.
- The internal tables can always be overridden by tables supplied by the
+ The internal tables can always be overridden by tables supplied by the
application that calls PCRE. These may be created in a different locale
- from the default. As more and more applications change to using Uni-
+ from the default. As more and more applications change to using Uni-
code, the need for this locale support is expected to die away.
- External tables are built by calling the pcre_maketables() function,
- which has no arguments, in the relevant locale. The result can then be
- passed to pcre_compile() or pcre_exec() as often as necessary. For
- example, to build and use tables that are appropriate for the French
- locale (where accented characters with values greater than 128 are
+ External tables are built by calling the pcre_maketables() function,
+ which has no arguments, in the relevant locale. The result can then be
+ passed to pcre_compile() or pcre_exec() as often as necessary. For
+ example, to build and use tables that are appropriate for the French
+ locale (where accented characters with values greater than 128 are
treated as letters), the following code could be used:
setlocale(LC_CTYPE, "fr_FR");
tables = pcre_maketables();
re = pcre_compile(..., tables);
- The locale name "fr_FR" is used on Linux and other Unix-like systems;
+ The locale name "fr_FR" is used on Linux and other Unix-like systems;
if you are using Windows, the name for the French locale is "french".
- When pcre_maketables() runs, the tables are built in memory that is
- obtained via pcre_malloc. It is the caller's responsibility to ensure
- that the memory containing the tables remains available for as long as
+ When pcre_maketables() runs, the tables are built in memory that is
+ obtained via pcre_malloc. It is the caller's responsibility to ensure
+ that the memory containing the tables remains available for as long as
it is needed.
The pointer that is passed to pcre_compile() is saved with the compiled
- pattern, and the same tables are used via this pointer by pcre_study()
+ pattern, and the same tables are used via this pointer by pcre_study()
and normally also by pcre_exec(). Thus, by default, for any single pat-
tern, compilation, studying and matching all happen in the same locale,
but different patterns can be compiled in different locales.
- It is possible to pass a table pointer or NULL (indicating the use of
- the internal tables) to pcre_exec(). Although not intended for this
- purpose, this facility could be used to match a pattern in a different
+ It is possible to pass a table pointer or NULL (indicating the use of
+ the internal tables) to pcre_exec(). Although not intended for this
+ purpose, this facility could be used to match a pattern in a different
locale from the one in which it was compiled. Passing table pointers at
run time is discussed below in the section on matching a pattern.
@@ -1655,32 +2063,35 @@
int pcre_fullinfo(const pcre *code, const pcre_extra *extra,
int what, void *where);
- The pcre_fullinfo() function returns information about a compiled pat-
- tern. It replaces the obsolete pcre_info() function, which is neverthe-
- less retained for backwards compability (and is documented below).
-
- The first argument for pcre_fullinfo() is a pointer to the compiled
- pattern. The second argument is the result of pcre_study(), or NULL if
- the pattern was not studied. The third argument specifies which piece
- of information is required, and the fourth argument is a pointer to a
- variable to receive the data. The yield of the function is zero for
+ The pcre_fullinfo() function returns information about a compiled pat-
+ tern. It replaces the pcre_info() function, which was removed from the
+ library at version 8.30, after more than 10 years of obsolescence.
+
+ The first argument for pcre_fullinfo() is a pointer to the compiled
+ pattern. The second argument is the result of pcre_study(), or NULL if
+ the pattern was not studied. The third argument specifies which piece
+ of information is required, and the fourth argument is a pointer to a
+ variable to receive the data. The yield of the function is zero for
success, or one of the following negative numbers:
- PCRE_ERROR_NULL the argument code was NULL
- the argument where was NULL
- PCRE_ERROR_BADMAGIC the "magic number" was not found
- PCRE_ERROR_BADOPTION the value of what was invalid
-
- The "magic number" is placed at the start of each compiled pattern as
- an simple check against passing an arbitrary memory pointer. Here is a
- typical call of pcre_fullinfo(), to obtain the length of the compiled
- pattern:
+ PCRE_ERROR_NULL the argument code was NULL
+ the argument where was NULL
+ PCRE_ERROR_BADMAGIC the "magic number" was not found
+ PCRE_ERROR_BADENDIANNESS the pattern was compiled with different
+ endianness
+ PCRE_ERROR_BADOPTION the value of what was invalid
+
+ The "magic number" is placed at the start of each compiled pattern as
+ an simple check against passing an arbitrary memory pointer. The endi-
+ anness error can occur if a compiled pattern is saved and reloaded on a
+ different host. Here is a typical call of pcre_fullinfo(), to obtain
+ the length of the compiled pattern:
int rc;
size_t length;
rc = pcre_fullinfo(
re, /* result of pcre_compile() */
- pe, /* result of pcre_study(), or NULL */
+ sd, /* result of pcre_study(), or NULL */
PCRE_INFO_SIZE, /* what is required */
&length); /* where to put the data */
@@ -1708,13 +2119,17 @@
PCRE_INFO_FIRSTBYTE
- Return information about the first byte of any matched string, for a
- non-anchored pattern. The fourth argument should point to an int vari-
- able. (This option used to be called PCRE_INFO_FIRSTCHAR; the old name
- is still recognized for backwards compatibility.)
+ Return information about the first data unit of any matched string, for
+ a non-anchored pattern. (The name of this option refers to the 8-bit
+ library, where data units are bytes.) The fourth argument should point
+ to an int variable.
+
+ If there is a fixed first value, for example, the letter "c" from a
+ pattern such as (cat|cow|coyote), its value is returned. In the 8-bit
+ library, the value is always less than 256; in the 16-bit library the
+ value can be up to 0xffff.
- If there is a fixed first byte, for example, from a pattern such as
- (cat|cow|coyote), its value is returned. Otherwise, if either
+ If there is no fixed first value, and if either
(a) the pattern was compiled with the PCRE_MULTILINE option, and every
branch starts with "^", or
@@ -1729,10 +2144,10 @@
PCRE_INFO_FIRSTTABLE
If the pattern was studied, and this resulted in the construction of a
- 256-bit table indicating a fixed set of bytes for the first byte in any
- matching string, a pointer to the table is returned. Otherwise NULL is
- returned. The fourth argument should point to an unsigned char * vari-
- able.
+ 256-bit table indicating a fixed set of values for the first data unit
+ in any matching string, a pointer to the table is returned. Otherwise
+ NULL is returned. The fourth argument should point to an unsigned char
+ * variable.
PCRE_INFO_HASCRORLF
@@ -1747,25 +2162,49 @@
otherwise 0. The fourth argument should point to an int variable. (?J)
and (?-J) set and unset the local PCRE_DUPNAMES option, respectively.
+ PCRE_INFO_JIT
+
+ Return 1 if the pattern was studied with one of the JIT options, and
+ just-in-time compiling was successful. The fourth argument should point
+ to an int variable. A return value of 0 means that JIT support is not
+ available in this version of PCRE, or that the pattern was not studied
+ with a JIT option, or that the JIT compiler could not handle this par-
+ ticular pattern. See the pcrejit documentation for details of what can
+ and cannot be handled.
+
+ PCRE_INFO_JITSIZE
+
+ If the pattern was successfully studied with a JIT option, return the
+ size of the JIT compiled code, otherwise return zero. The fourth argu-
+ ment should point to a size_t variable.
+
PCRE_INFO_LASTLITERAL
- Return the value of the rightmost literal byte that must exist in any
- matched string, other than at its start, if such a byte has been
+ Return the value of the rightmost literal data unit that must exist in
+ any matched string, other than at its start, if such a value has been
recorded. The fourth argument should point to an int variable. If there
- is no such byte, -1 is returned. For anchored patterns, a last literal
- byte is recorded only if it follows something of variable length. For
+ is no such value, -1 is returned. For anchored patterns, a last literal
+ value is recorded only if it follows something of variable length. For
example, for the pattern /^a\d+z\d+/ the returned value is "z", but for
/^a\dz\d/ the returned value is -1.
+ PCRE_INFO_MAXLOOKBEHIND
+
+ Return the number of characters (NB not bytes) in the longest lookbe-
+ hind assertion in the pattern. Note that the simple assertions \b and
+ \B require a one-character lookbehind. This information is useful when
+ doing multi-segment matching using the partial matching facilities.
+
PCRE_INFO_MINLENGTH
- If the pattern was studied and a minimum length for matching subject
- strings was computed, its value is returned. Otherwise the returned
- value is -1. The value is a number of characters, not bytes (this may
- be relevant in UTF-8 mode). The fourth argument should point to an int
- variable. A non-negative value is a lower bound to the length of any
- matching string. There may not be any strings of that length that do
- actually match, but every string that does match is at least that long.
+ If the pattern was studied and a minimum length for matching subject
+ strings was computed, its value is returned. Otherwise the returned
+ value is -1. The value is a number of characters, which in UTF-8 mode
+ may be different from the number of bytes. The fourth argument should
+ point to an int variable. A non-negative value is a lower bound to the
+ length of any matching string. There may not be any strings of that
+ length that do actually match, but every string that does match is at
+ least that long.
PCRE_INFO_NAMECOUNT
PCRE_INFO_NAMEENTRYSIZE
@@ -1785,10 +2224,12 @@
gives the number of entries, and PCRE_INFO_NAMEENTRYSIZE gives the size
of each entry; both of these return an int value. The entry size
depends on the length of the longest name. PCRE_INFO_NAMETABLE returns
- a pointer to the first entry of the table (a pointer to char). The
- first two bytes of each entry are the number of the capturing parenthe-
- sis, most significant byte first. The rest of the entry is the corre-
- sponding name, zero terminated.
+ a pointer to the first entry of the table. This is a pointer to char in
+ the 8-bit library, where the first two bytes of each entry are the num-
+ ber of the capturing parenthesis, most significant byte first. In the
+ 16-bit library, the pointer points to 16-bit data units, the first of
+ which contains the parenthesis number. The rest of the entry is the
+ corresponding name, zero terminated.
The names are in alphabetical order. Duplicate names may appear if (?|
is used to create multiple groups with the same number, as described in
@@ -1801,8 +2242,8 @@
terns may have lower numbers.
As a simple example of the name/number table, consider the following
- pattern (assume PCRE_EXTENDED is set, so white space - including new-
- lines - is ignored):
+ pattern after compilation by the 8-bit library (assume PCRE_EXTENDED is
+ set, so white space - including newlines - is ignored):
(? (?(\d\d)?\d\d) -
(?\d\d) - (?\d\d) )
@@ -1855,62 +2296,47 @@
PCRE_INFO_SIZE
- Return the size of the compiled pattern, that is, the value that was
- passed as the argument to pcre_malloc() when PCRE was getting memory in
- which to place the compiled data. The fourth argument should point to a
- size_t variable.
+ Return the size of the compiled pattern in bytes (for both libraries).
+ The fourth argument should point to a size_t variable. This value does
+ not include the size of the pcre structure that is returned by
+ pcre_compile(). The value that is passed as the argument to pcre_mal-
+ loc() when pcre_compile() is getting memory in which to place the com-
+ piled data is the value returned by this option plus the size of the
+ pcre structure. Studying a compiled pattern, with or without JIT, does
+ not alter the value returned by this option.
PCRE_INFO_STUDYSIZE
- Return the size of the data block pointed to by the study_data field in
- a pcre_extra block. That is, it is the value that was passed to
- pcre_malloc() when PCRE was getting memory into which to place the data
- created by pcre_study(). If pcre_extra is NULL, or there is no study
- data, zero is returned. The fourth argument should point to a size_t
- variable.
-
-
-OBSOLETE INFO FUNCTION
-
- int pcre_info(const pcre *code, int *optptr, int *firstcharptr);
-
- The pcre_info() function is now obsolete because its interface is too
- restrictive to return all the available data about a compiled pattern.
- New programs should use pcre_fullinfo() instead. The yield of
- pcre_info() is the number of capturing subpatterns, or one of the fol-
- lowing negative numbers:
-
- PCRE_ERROR_NULL the argument code was NULL
- PCRE_ERROR_BADMAGIC the "magic number" was not found
-
- If the optptr argument is not NULL, a copy of the options with which
- the pattern was compiled is placed in the integer it points to (see
- PCRE_INFO_OPTIONS above).
-
- If the pattern is not anchored and the firstcharptr argument is not
- NULL, it is used to pass back information about the first character of
- any matched string (see PCRE_INFO_FIRSTBYTE above).
+ Return the size in bytes of the data block pointed to by the study_data
+ field in a pcre_extra block. If pcre_extra is NULL, or there is no
+ study data, zero is returned. The fourth argument should point to a
+ size_t variable. The study_data field is set by pcre_study() to record
+ information that will speed up matching (see the section entitled
+ "Studying a pattern" above). The format of the study_data block is pri-
+ vate, but its length is made available via this option so that it can
+ be saved and restored (see the pcreprecompile documentation for
+ details).
REFERENCE COUNTS
int pcre_refcount(pcre *code, int adjust);
- The pcre_refcount() function is used to maintain a reference count in
+ The pcre_refcount() function is used to maintain a reference count in
the data block that contains a compiled pattern. It is provided for the
- benefit of applications that operate in an object-oriented manner,
+ benefit of applications that operate in an object-oriented manner,
where different parts of the application may be using the same compiled
pattern, but you want to free the block when they are all done.
When a pattern is compiled, the reference count field is initialized to
- zero. It is changed only by calling this function, whose action is to
- add the adjust value (which may be positive or negative) to it. The
+ zero. It is changed only by calling this function, whose action is to
+ add the adjust value (which may be positive or negative) to it. The
yield of the function is the new value. However, the value of the count
- is constrained to lie between 0 and 65535, inclusive. If the new value
+ is constrained to lie between 0 and 65535, inclusive. If the new value
is outside these limits, it is forced to the appropriate limit value.
- Except when it is zero, the reference count is not correctly preserved
- if a pattern is compiled on one host and then transferred to a host
+ Except when it is zero, the reference count is not correctly preserved
+ if a pattern is compiled on one host and then transferred to a host
whose byte-order is different. (This seems a highly unlikely scenario.)
@@ -1920,18 +2346,22 @@
const char *subject, int length, int startoffset,
int options, int *ovector, int ovecsize);
- The function pcre_exec() is called to match a subject string against a
- compiled pattern, which is passed in the code argument. If the pattern
- was studied, the result of the study should be passed in the extra
- argument. This function is the main matching facility of the library,
- and it operates in a Perl-like manner. For specialist use there is also
- an alternative matching function, which is described below in the sec-
- tion about the pcre_dfa_exec() function.
+ The function pcre_exec() is called to match a subject string against a
+ compiled pattern, which is passed in the code argument. If the pattern
+ was studied, the result of the study should be passed in the extra
+ argument. You can call pcre_exec() with the same code and extra argu-
+ ments as many times as you like, in order to match different subject
+ strings with the same pattern.
+
+ This function is the main matching facility of the library, and it
+ operates in a Perl-like manner. For specialist use there is also an
+ alternative matching function, which is described below in the section
+ about the pcre_dfa_exec() function.
- In most applications, the pattern will have been compiled (and option-
- ally studied) in the same process that calls pcre_exec(). However, it
+ In most applications, the pattern will have been compiled (and option-
+ ally studied) in the same process that calls pcre_exec(). However, it
is possible to save compiled patterns and study data, and then use them
- later in different processes, possibly even on different hosts. For a
+ later in different processes, possibly even on different hosts. For a
discussion about this, see the pcreprecompile documentation.
Here is an example of a simple call to pcre_exec():
@@ -1950,35 +2380,40 @@
Extra data for pcre_exec()
- If the extra argument is not NULL, it must point to a pcre_extra data
- block. The pcre_study() function returns such a block (when it doesn't
- return NULL), but you can also create one for yourself, and pass addi-
- tional information in it. The pcre_extra block contains the following
+ If the extra argument is not NULL, it must point to a pcre_extra data
+ block. The pcre_study() function returns such a block (when it doesn't
+ return NULL), but you can also create one for yourself, and pass addi-
+ tional information in it. The pcre_extra block contains the following
fields (not necessarily in this order):
unsigned long int flags;
void *study_data;
+ void *executable_jit;
unsigned long int match_limit;
unsigned long int match_limit_recursion;
void *callout_data;
const unsigned char *tables;
unsigned char **mark;
- The flags field is a bitmap that specifies which of the other fields
- are set. The flag bits are:
+ In the 16-bit version of this structure, the mark field has type
+ "PCRE_UCHAR16 **".
- PCRE_EXTRA_STUDY_DATA
+ The flags field is used to specify which of the other fields are set.
+ The flag bits are:
+
+ PCRE_EXTRA_CALLOUT_DATA
+ PCRE_EXTRA_EXECUTABLE_JIT
+ PCRE_EXTRA_MARK
PCRE_EXTRA_MATCH_LIMIT
PCRE_EXTRA_MATCH_LIMIT_RECURSION
- PCRE_EXTRA_CALLOUT_DATA
+ PCRE_EXTRA_STUDY_DATA
PCRE_EXTRA_TABLES
- PCRE_EXTRA_MARK
- Other flag bits should be set to zero. The study_data field is set in
- the pcre_extra block that is returned by pcre_study(), together with
- the appropriate flag bit. You should not set this yourself, but you may
- add to the block by setting the other fields and their corresponding
- flag bits.
+ Other flag bits should be set to zero. The study_data field and some-
+ times the executable_jit field are set in the pcre_extra block that is
+ returned by pcre_study(), together with the appropriate flag bits. You
+ should not set these yourself, but you may add to the block by setting
+ other fields and their corresponding flag bits.
The match_limit field provides a means of preventing PCRE from using up
a vast amount of resources when running patterns that are not going to
@@ -1986,70 +2421,86 @@
search trees. The classic example is a pattern that uses nested unlim-
ited repeats.
- Internally, PCRE uses a function called match() which it calls repeat-
- edly (sometimes recursively). The limit set by match_limit is imposed
- on the number of times this function is called during a match, which
- has the effect of limiting the amount of backtracking that can take
- place. For patterns that are not anchored, the count restarts from zero
- for each position in the subject string.
-
- The default value for the limit can be set when PCRE is built; the
- default default is 10 million, which handles all but the most extreme
- cases. You can override the default by suppling pcre_exec() with a
- pcre_extra block in which match_limit is set, and
- PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is
+ Internally, pcre_exec() uses a function called match(), which it calls
+ repeatedly (sometimes recursively). The limit set by match_limit is
+ imposed on the number of times this function is called during a match,
+ which has the effect of limiting the amount of backtracking that can
+ take place. For patterns that are not anchored, the count restarts from
+ zero for each position in the subject string.
+
+ When pcre_exec() is called with a pattern that was successfully studied
+ with a JIT option, the way that the matching is executed is entirely
+ different. However, there is still the possibility of runaway matching
+ that goes on for a very long time, and so the match_limit value is also
+ used in this case (but in a different way) to limit how long the match-
+ ing can continue.
+
+ The default value for the limit can be set when PCRE is built; the
+ default default is 10 million, which handles all but the most extreme
+ cases. You can override the default by suppling pcre_exec() with a
+ pcre_extra block in which match_limit is set, and
+ PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is
exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT.
- The match_limit_recursion field is similar to match_limit, but instead
+ The match_limit_recursion field is similar to match_limit, but instead
of limiting the total number of times that match() is called, it limits
- the depth of recursion. The recursion depth is a smaller number than
- the total number of calls, because not all calls to match() are recur-
+ the depth of recursion. The recursion depth is a smaller number than
+ the total number of calls, because not all calls to match() are recur-
sive. This limit is of use only if it is set smaller than match_limit.
- Limiting the recursion depth limits the amount of stack that can be
- used, or, when PCRE has been compiled to use memory on the heap instead
- of the stack, the amount of heap memory that can be used.
-
- The default value for match_limit_recursion can be set when PCRE is
- built; the default default is the same value as the default for
- match_limit. You can override the default by suppling pcre_exec() with
- a pcre_extra block in which match_limit_recursion is set, and
- PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the
+ Limiting the recursion depth limits the amount of machine stack that
+ can be used, or, when PCRE has been compiled to use memory on the heap
+ instead of the stack, the amount of heap memory that can be used. This
+ limit is not relevant, and is ignored, when matching is done using JIT
+ compiled code.
+
+ The default value for match_limit_recursion can be set when PCRE is
+ built; the default default is the same value as the default for
+ match_limit. You can override the default by suppling pcre_exec() with
+ a pcre_extra block in which match_limit_recursion is set, and
+ PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the
limit is exceeded, pcre_exec() returns PCRE_ERROR_RECURSIONLIMIT.
- The callout_data field is used in conjunction with the "callout" fea-
+ The callout_data field is used in conjunction with the "callout" fea-
ture, and is described in the pcrecallout documentation.
- The tables field is used to pass a character tables pointer to
- pcre_exec(); this overrides the value that is stored with the compiled
- pattern. A non-NULL value is stored with the compiled pattern only if
- custom tables were supplied to pcre_compile() via its tableptr argu-
+ The tables field is used to pass a character tables pointer to
+ pcre_exec(); this overrides the value that is stored with the compiled
+ pattern. A non-NULL value is stored with the compiled pattern only if
+ custom tables were supplied to pcre_compile() via its tableptr argu-
ment. If NULL is passed to pcre_exec() using this mechanism, it forces
- PCRE's internal tables to be used. This facility is helpful when re-
- using patterns that have been saved after compiling with an external
- set of tables, because the external tables might be at a different
- address when pcre_exec() is called. See the pcreprecompile documenta-
+ PCRE's internal tables to be used. This facility is helpful when re-
+ using patterns that have been saved after compiling with an external
+ set of tables, because the external tables might be at a different
+ address when pcre_exec() is called. See the pcreprecompile documenta-
tion for a discussion of saving compiled patterns for later use.
- If PCRE_EXTRA_MARK is set in the flags field, the mark field must be
- set to point to a char * variable. If the pattern contains any back-
- tracking control verbs such as (*MARK:NAME), and the execution ends up
- with a name to pass back, a pointer to the name string (zero termi-
- nated) is placed in the variable pointed to by the mark field. The
- names are within the compiled pattern; if you wish to retain such a
- name you must copy it before freeing the memory of a compiled pattern.
- If there is no name to pass back, the variable pointed to by the mark
- field set to NULL. For details of the backtracking control verbs, see
- the section entitled "Backtracking control" in the pcrepattern documen-
- tation.
+ If PCRE_EXTRA_MARK is set in the flags field, the mark field must be
+ set to point to a suitable variable. If the pattern contains any back-
+ tracking control verbs such as (*MARK:NAME), and the execution ends up
+ with a name to pass back, a pointer to the name string (zero termi-
+ nated) is placed in the variable pointed to by the mark field. The
+ names are within the compiled pattern; if you wish to retain such a
+ name you must copy it before freeing the memory of a compiled pattern.
+ If there is no name to pass back, the variable pointed to by the mark
+ field is set to NULL. For details of the backtracking control verbs,
+ see the section entitled "Backtracking control" in the pcrepattern doc-
+ umentation.
Option bits for pcre_exec()
- The unused bits of the options argument for pcre_exec() must be zero.
- The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx,
- PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART,
- PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_SOFT, and
- PCRE_PARTIAL_HARD.
+ The unused bits of the options argument for pcre_exec() must be zero.
+ The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx,
+ PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART,
+ PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and
+ PCRE_PARTIAL_SOFT.
+
+ If the pattern was successfully studied with one of the just-in-time
+ (JIT) compile options, the only supported options for JIT execution are
+ PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY,
+ PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an
+ unsupported option is used, JIT execution is disabled and the normal
+ interpretive code in pcre_exec() is run.
PCRE_ANCHORED
@@ -2172,7 +2623,9 @@
where the result is "no match", the callouts do occur, and that items
such as (*COMMIT) and (*MARK) are considered at every possible starting
position in the subject string. If PCRE_NO_START_OPTIMIZE is set at
- compile time, it cannot be unset at matching time.
+ compile time, it cannot be unset at matching time. The use of
+ PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, matching
+ is always done using interpretively.
Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching
operation. Consider the pattern
@@ -2206,182 +2659,201 @@
When PCRE_UTF8 is set at compile time, the validity of the subject as a
UTF-8 string is automatically checked when pcre_exec() is subsequently
- called. The value of startoffset is also checked to ensure that it
- points to the start of a UTF-8 character. There is a discussion about
- the validity of UTF-8 strings in the section on UTF-8 support in the
- main pcre page. If an invalid UTF-8 sequence of bytes is found,
- pcre_exec() returns the error PCRE_ERROR_BADUTF8 or, if PCRE_PAR-
- TIAL_HARD is set and the problem is a truncated UTF-8 character at the
- end of the subject, PCRE_ERROR_SHORTUTF8. If startoffset contains a
- value that does not point to the start of a UTF-8 character (or to the
- end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned.
-
- If you already know that your subject is valid, and you want to skip
- these checks for performance reasons, you can set the
- PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to
- do this for the second and subsequent calls to pcre_exec() if you are
- making repeated calls to find all the matches in a single subject
- string. However, you should be sure that the value of startoffset
- points to the start of a UTF-8 character (or the end of the subject).
- When PCRE_NO_UTF8_CHECK is set, the effect of passing an invalid UTF-8
- string as a subject or an invalid value of startoffset is undefined.
- Your program may crash.
+ called. The entire string is checked before any other processing takes
+ place. The value of startoffset is also checked to ensure that it
+ points to the start of a UTF-8 character. There is a discussion about
+ the validity of UTF-8 strings in the pcreunicode page. If an invalid
+ sequence of bytes is found, pcre_exec() returns the error
+ PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a
+ truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In
+ both cases, information about the precise nature of the error may also
+ be returned (see the descriptions of these errors in the section enti-
+ tled Error return values from pcre_exec() below). If startoffset con-
+ tains a value that does not point to the start of a UTF-8 character (or
+ to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned.
+
+ If you already know that your subject is valid, and you want to skip
+ these checks for performance reasons, you can set the
+ PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to
+ do this for the second and subsequent calls to pcre_exec() if you are
+ making repeated calls to find all the matches in a single subject
+ string. However, you should be sure that the value of startoffset
+ points to the start of a character (or the end of the subject). When
+ PCRE_NO_UTF8_CHECK is set, the effect of passing an invalid string as a
+ subject or an invalid value of startoffset is undefined. Your program
+ may crash.
PCRE_PARTIAL_HARD
PCRE_PARTIAL_SOFT
- These options turn on the partial matching feature. For backwards com-
- patibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial
- match occurs if the end of the subject string is reached successfully,
- but there are not enough subject characters to complete the match. If
+ These options turn on the partial matching feature. For backwards com-
+ patibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial
+ match occurs if the end of the subject string is reached successfully,
+ but there are not enough subject characters to complete the match. If
this happens when PCRE_PARTIAL_SOFT (but not PCRE_PARTIAL_HARD) is set,
- matching continues by testing any remaining alternatives. Only if no
- complete match can be found is PCRE_ERROR_PARTIAL returned instead of
- PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the
- caller is prepared to handle a partial match, but only if no complete
+ matching continues by testing any remaining alternatives. Only if no
+ complete match can be found is PCRE_ERROR_PARTIAL returned instead of
+ PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the
+ caller is prepared to handle a partial match, but only if no complete
match can be found.
- If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this
- case, if a partial match is found, pcre_exec() immediately returns
- PCRE_ERROR_PARTIAL, without considering any other alternatives. In
- other words, when PCRE_PARTIAL_HARD is set, a partial match is consid-
+ If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this
+ case, if a partial match is found, pcre_exec() immediately returns
+ PCRE_ERROR_PARTIAL, without considering any other alternatives. In
+ other words, when PCRE_PARTIAL_HARD is set, a partial match is consid-
ered to be more important that an alternative complete match.
- In both cases, the portion of the string that was inspected when the
+ In both cases, the portion of the string that was inspected when the
partial match was found is set as the first matching string. There is a
- more detailed discussion of partial and multi-segment matching, with
+ more detailed discussion of partial and multi-segment matching, with
examples, in the pcrepartial documentation.
The string to be matched by pcre_exec()
- The subject string is passed to pcre_exec() as a pointer in subject, a
- length (in bytes) in length, and a starting byte offset in startoffset.
- If this is negative or greater than the length of the subject,
- pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is
- zero, the search for a match starts at the beginning of the subject,
+ The subject string is passed to pcre_exec() as a pointer in subject, a
+ length in bytes in length, and a starting byte offset in startoffset.
+ If this is negative or greater than the length of the subject,
+ pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is
+ zero, the search for a match starts at the beginning of the subject,
and this is by far the most common case. In UTF-8 mode, the byte offset
- must point to the start of a UTF-8 character (or the end of the sub-
- ject). Unlike the pattern string, the subject may contain binary zero
+ must point to the start of a UTF-8 character (or the end of the sub-
+ ject). Unlike the pattern string, the subject may contain binary zero
bytes.
- A non-zero starting offset is useful when searching for another match
- in the same subject by calling pcre_exec() again after a previous suc-
- cess. Setting startoffset differs from just passing over a shortened
- string and setting PCRE_NOTBOL in the case of a pattern that begins
+ A non-zero starting offset is useful when searching for another match
+ in the same subject by calling pcre_exec() again after a previous suc-
+ cess. Setting startoffset differs from just passing over a shortened
+ string and setting PCRE_NOTBOL in the case of a pattern that begins
with any kind of lookbehind. For example, consider the pattern
\Biss\B
- which finds occurrences of "iss" in the middle of words. (\B matches
- only if the current position in the subject is not a word boundary.)
- When applied to the string "Mississipi" the first call to pcre_exec()
- finds the first occurrence. If pcre_exec() is called again with just
- the remainder of the subject, namely "issipi", it does not match,
+ which finds occurrences of "iss" in the middle of words. (\B matches
+ only if the current position in the subject is not a word boundary.)
+ When applied to the string "Mississipi" the first call to pcre_exec()
+ finds the first occurrence. If pcre_exec() is called again with just
+ the remainder of the subject, namely "issipi", it does not match,
because \B is always false at the start of the subject, which is deemed
- to be a word boundary. However, if pcre_exec() is passed the entire
+ to be a word boundary. However, if pcre_exec() is passed the entire
string again, but with startoffset set to 4, it finds the second occur-
- rence of "iss" because it is able to look behind the starting point to
+ rence of "iss" because it is able to look behind the starting point to
discover that it is preceded by a letter.
- Finding all the matches in a subject is tricky when the pattern can
+ Finding all the matches in a subject is tricky when the pattern can
match an empty string. It is possible to emulate Perl's /g behaviour by
- first trying the match again at the same offset, with the
- PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that
- fails, advancing the starting offset and trying an ordinary match
+ first trying the match again at the same offset, with the
+ PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that
+ fails, advancing the starting offset and trying an ordinary match
again. There is some code that demonstrates how to do this in the pcre-
demo sample program. In the most general case, you have to check to see
- if the newline convention recognizes CRLF as a newline, and if so, and
+ if the newline convention recognizes CRLF as a newline, and if so, and
the current character is CR followed by LF, advance the starting offset
by two characters instead of one.
- If a non-zero starting offset is passed when the pattern is anchored,
+ If a non-zero starting offset is passed when the pattern is anchored,
one attempt to match at the given offset is made. This can only succeed
- if the pattern does not require the match to be at the start of the
+ if the pattern does not require the match to be at the start of the
subject.
How pcre_exec() returns captured substrings
- In general, a pattern matches a certain portion of the subject, and in
- addition, further substrings from the subject may be picked out by
- parts of the pattern. Following the usage in Jeffrey Friedl's book,
- this is called "capturing" in what follows, and the phrase "capturing
- subpattern" is used for a fragment of a pattern that picks out a sub-
- string. PCRE supports several other kinds of parenthesized subpattern
+ In general, a pattern matches a certain portion of the subject, and in
+ addition, further substrings from the subject may be picked out by
+ parts of the pattern. Following the usage in Jeffrey Friedl's book,
+ this is called "capturing" in what follows, and the phrase "capturing
+ subpattern" is used for a fragment of a pattern that picks out a sub-
+ string. PCRE supports several other kinds of parenthesized subpattern
that do not cause substrings to be captured.
Captured substrings are returned to the caller via a vector of integers
- whose address is passed in ovector. The number of elements in the vec-
- tor is passed in ovecsize, which must be a non-negative number. Note:
+ whose address is passed in ovector. The number of elements in the vec-
+ tor is passed in ovecsize, which must be a non-negative number. Note:
this argument is NOT the size of ovector in bytes.
- The first two-thirds of the vector is used to pass back captured sub-
- strings, each substring using a pair of integers. The remaining third
- of the vector is used as workspace by pcre_exec() while matching cap-
- turing subpatterns, and is not available for passing back information.
- The number passed in ovecsize should always be a multiple of three. If
+ The first two-thirds of the vector is used to pass back captured sub-
+ strings, each substring using a pair of integers. The remaining third
+ of the vector is used as workspace by pcre_exec() while matching cap-
+ turing subpatterns, and is not available for passing back information.
+ The number passed in ovecsize should always be a multiple of three. If
it is not, it is rounded down.
- When a match is successful, information about captured substrings is
- returned in pairs of integers, starting at the beginning of ovector,
- and continuing up to two-thirds of its length at the most. The first
- element of each pair is set to the byte offset of the first character
- in a substring, and the second is set to the byte offset of the first
- character after the end of a substring. Note: these values are always
+ When a match is successful, information about captured substrings is
+ returned in pairs of integers, starting at the beginning of ovector,
+ and continuing up to two-thirds of its length at the most. The first
+ element of each pair is set to the byte offset of the first character
+ in a substring, and the second is set to the byte offset of the first
+ character after the end of a substring. Note: these values are always
byte offsets, even in UTF-8 mode. They are not character counts.
- The first pair of integers, ovector[0] and ovector[1], identify the
- portion of the subject string matched by the entire pattern. The next
- pair is used for the first capturing subpattern, and so on. The value
+ The first pair of integers, ovector[0] and ovector[1], identify the
+ portion of the subject string matched by the entire pattern. The next
+ pair is used for the first capturing subpattern, and so on. The value
returned by pcre_exec() is one more than the highest numbered pair that
- has been set. For example, if two substrings have been captured, the
- returned value is 3. If there are no capturing subpatterns, the return
+ has been set. For example, if two substrings have been captured, the
+ returned value is 3. If there are no capturing subpatterns, the return
value from a successful match is 1, indicating that just the first pair
of offsets has been set.
If a capturing subpattern is matched repeatedly, it is the last portion
of the string that it matched that is returned.
- If the vector is too small to hold all the captured substring offsets,
+ If the vector is too small to hold all the captured substring offsets,
it is used as far as possible (up to two-thirds of its length), and the
- function returns a value of zero. If the substring offsets are not of
- interest, pcre_exec() may be called with ovector passed as NULL and
- ovecsize as zero. However, if the pattern contains back references and
- the ovector is not big enough to remember the related substrings, PCRE
- has to get additional memory for use during matching. Thus it is usu-
- ally advisable to supply an ovector.
+ function returns a value of zero. If neither the actual string matched
+ nor any captured substrings are of interest, pcre_exec() may be called
+ with ovector passed as NULL and ovecsize as zero. However, if the pat-
+ tern contains back references and the ovector is not big enough to
+ remember the related substrings, PCRE has to get additional memory for
+ use during matching. Thus it is usually advisable to supply an ovector
+ of reasonable size.
+
+ There are some cases where zero is returned (indicating vector over-
+ flow) when in fact the vector is exactly the right size for the final
+ match. For example, consider the pattern
+
+ (a)(?:(b)c|bd)
+
+ If a vector of 6 elements (allowing for only 1 captured substring) is
+ given with subject string "abd", pcre_exec() will try to set the second
+ captured string, thereby recording a vector overflow, before failing to
+ match "c" and backing up to try the second alternative. The zero
+ return, however, does correctly indicate that the maximum number of
+ slots (namely 2) have been filled. In similar cases where there is tem-
+ porary overflow, but the final number of used slots is actually less
+ than the maximum, a non-zero value is returned.
The pcre_fullinfo() function can be used to find out how many capturing
- subpatterns there are in a compiled pattern. The smallest size for
- ovector that will allow for n captured substrings, in addition to the
+ subpatterns there are in a compiled pattern. The smallest size for
+ ovector that will allow for n captured substrings, in addition to the
offsets of the substring matched by the whole pattern, is (n+1)*3.
- It is possible for capturing subpattern number n+1 to match some part
+ It is possible for capturing subpattern number n+1 to match some part
of the subject when subpattern n has not been used at all. For example,
- if the string "abc" is matched against the pattern (a|(z))(bc) the
+ if the string "abc" is matched against the pattern (a|(z))(bc) the
return from the function is 4, and subpatterns 1 and 3 are matched, but
- 2 is not. When this happens, both values in the offset pairs corre-
+ 2 is not. When this happens, both values in the offset pairs corre-
sponding to unused subpatterns are set to -1.
- Offset values that correspond to unused subpatterns at the end of the
- expression are also set to -1. For example, if the string "abc" is
- matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3 are not
- matched. The return from the function is 2, because the highest used
- capturing subpattern number is 1, and the offsets for for the second
- and third capturing subpatterns (assuming the vector is large enough,
+ Offset values that correspond to unused subpatterns at the end of the
+ expression are also set to -1. For example, if the string "abc" is
+ matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3 are not
+ matched. The return from the function is 2, because the highest used
+ capturing subpattern number is 1, and the offsets for for the second
+ and third capturing subpatterns (assuming the vector is large enough,
of course) are set to -1.
- Note: Elements of ovector that do not correspond to capturing parenthe-
- ses in the pattern are never changed. That is, if a pattern contains n
- capturing parentheses, no more than ovector[0] to ovector[2n+1] are set
- by pcre_exec(). The other elements retain whatever values they previ-
- ously had.
+ Note: Elements in the first two-thirds of ovector that do not corre-
+ spond to capturing parentheses in the pattern are never changed. That
+ is, if a pattern contains n capturing parentheses, no more than ovec-
+ tor[0] to ovector[2n+1] are set by pcre_exec(). The other elements (in
+ the first two-thirds) retain whatever values they previously had.
- Some convenience functions are provided for extracting the captured
+ Some convenience functions are provided for extracting the captured
substrings as separate strings. These are described below.
Error return values from pcre_exec()
- If pcre_exec() fails, it returns a negative number. The following are
+ If pcre_exec() fails, it returns a negative number. The following are
defined in the header file:
PCRE_ERROR_NOMATCH (-1)
@@ -2390,7 +2862,7 @@
PCRE_ERROR_NULL (-2)
- Either code or subject was passed as NULL, or ovector was NULL and
+ Either code or subject was passed as NULL, or ovector was NULL and
ovecsize was not zero.
PCRE_ERROR_BADOPTION (-3)
@@ -2399,76 +2871,82 @@
PCRE_ERROR_BADMAGIC (-4)
- PCRE stores a 4-byte "magic number" at the start of the compiled code,
+ PCRE stores a 4-byte "magic number" at the start of the compiled code,
to catch the case when it is passed a junk pointer and to detect when a
pattern that was compiled in an environment of one endianness is run in
- an environment with the other endianness. This is the error that PCRE
+ an environment with the other endianness. This is the error that PCRE
gives when the magic number is not present.
PCRE_ERROR_UNKNOWN_OPCODE (-5)
While running the pattern match, an unknown item was encountered in the
- compiled pattern. This error could be caused by a bug in PCRE or by
+ compiled pattern. This error could be caused by a bug in PCRE or by
overwriting of the compiled pattern.
PCRE_ERROR_NOMEMORY (-6)
- If a pattern contains back references, but the ovector that is passed
+ If a pattern contains back references, but the ovector that is passed
to pcre_exec() is not big enough to remember the referenced substrings,
- PCRE gets a block of memory at the start of matching to use for this
- purpose. If the call via pcre_malloc() fails, this error is given. The
+ PCRE gets a block of memory at the start of matching to use for this
+ purpose. If the call via pcre_malloc() fails, this error is given. The
memory is automatically freed at the end of matching.
- This error is also given if pcre_stack_malloc() fails in pcre_exec().
- This can happen only when PCRE has been compiled with --disable-stack-
+ This error is also given if pcre_stack_malloc() fails in pcre_exec().
+ This can happen only when PCRE has been compiled with --disable-stack-
for-recursion.
PCRE_ERROR_NOSUBSTRING (-7)
- This error is used by the pcre_copy_substring(), pcre_get_substring(),
+ This error is used by the pcre_copy_substring(), pcre_get_substring(),
and pcre_get_substring_list() functions (see below). It is never
returned by pcre_exec().
PCRE_ERROR_MATCHLIMIT (-8)
- The backtracking limit, as specified by the match_limit field in a
- pcre_extra structure (or defaulted) was reached. See the description
+ The backtracking limit, as specified by the match_limit field in a
+ pcre_extra structure (or defaulted) was reached. See the description
above.
PCRE_ERROR_CALLOUT (-9)
This error is never generated by pcre_exec() itself. It is provided for
- use by callout functions that want to yield a distinctive error code.
+ use by callout functions that want to yield a distinctive error code.
See the pcrecallout documentation for details.
PCRE_ERROR_BADUTF8 (-10)
- A string that contains an invalid UTF-8 byte sequence was passed as a
- subject. However, if PCRE_PARTIAL_HARD is set and the problem is a
- truncated UTF-8 character at the end of the subject, PCRE_ERROR_SHORT-
- UTF8 is used instead.
+ A string that contains an invalid UTF-8 byte sequence was passed as a
+ subject, and the PCRE_NO_UTF8_CHECK option was not set. If the size of
+ the output vector (ovecsize) is at least 2, the byte offset to the
+ start of the the invalid UTF-8 character is placed in the first ele-
+ ment, and a reason code is placed in the second element. The reason
+ codes are listed in the following section. For backward compatibility,
+ if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 char-
+ acter at the end of the subject (reason codes 1 to 5),
+ PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8.
PCRE_ERROR_BADUTF8_OFFSET (-11)
- The UTF-8 byte sequence that was passed as a subject was valid, but the
- value of startoffset did not point to the beginning of a UTF-8 charac-
+ The UTF-8 byte sequence that was passed as a subject was checked and
+ found to be valid (the PCRE_NO_UTF8_CHECK option was not set), but the
+ value of startoffset did not point to the beginning of a UTF-8 charac-
ter or the end of the subject.
PCRE_ERROR_PARTIAL (-12)
- The subject string did not match, but it did match partially. See the
+ The subject string did not match, but it did match partially. See the
pcrepartial documentation for details of partial matching.
PCRE_ERROR_BADPARTIAL (-13)
- This code is no longer in use. It was formerly returned when the
- PCRE_PARTIAL option was used with a compiled pattern containing items
- that were not supported for partial matching. From release 8.00
+ This code is no longer in use. It was formerly returned when the
+ PCRE_PARTIAL option was used with a compiled pattern containing items
+ that were not supported for partial matching. From release 8.00
onwards, there are no restrictions on partial matching.
PCRE_ERROR_INTERNAL (-14)
- An unexpected internal error has occurred. This error could be caused
+ An unexpected internal error has occurred. This error could be caused
by a bug in PCRE or by overwriting of the compiled pattern.
PCRE_ERROR_BADCOUNT (-15)
@@ -2478,7 +2956,7 @@
PCRE_ERROR_RECURSIONLIMIT (-21)
The internal recursion limit, as specified by the match_limit_recursion
- field in a pcre_extra structure (or defaulted) was reached. See the
+ field in a pcre_extra structure (or defaulted) was reached. See the
description above.
PCRE_ERROR_BADNEWLINE (-23)
@@ -2492,11 +2970,118 @@
PCRE_ERROR_SHORTUTF8 (-25)
- The subject string ended with an incomplete (truncated) UTF-8 charac-
- ter, and the PCRE_PARTIAL_HARD option was set. Without this option,
- PCRE_ERROR_BADUTF8 is returned in this situation.
+ This error is returned instead of PCRE_ERROR_BADUTF8 when the subject
+ string ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD
+ option is set. Information about the failure is returned as for
+ PCRE_ERROR_BADUTF8. It is in fact sufficient to detect this case, but
+ this special error code for PCRE_PARTIAL_HARD precedes the implementa-
+ tion of returned information; it is retained for backwards compatibil-
+ ity.
+
+ PCRE_ERROR_RECURSELOOP (-26)
+
+ This error is returned when pcre_exec() detects a recursion loop within
+ the pattern. Specifically, it means that either the whole pattern or a
+ subpattern has been called recursively for the second time at the same
+ position in the subject string. Some simple patterns that might do this
+ are detected and faulted at compile time, but more complicated cases,
+ in particular mutual recursions between two different subpatterns, can-
+ not be detected until run time.
+
+ PCRE_ERROR_JIT_STACKLIMIT (-27)
+
+ This error is returned when a pattern that was successfully studied
+ using a JIT compile option is being matched, but the memory available
+ for the just-in-time processing stack is not large enough. See the
+ pcrejit documentation for more details.
+
+ PCRE_ERROR_BADMODE (-28)
+
+ This error is given if a pattern that was compiled by the 8-bit library
+ is passed to a 16-bit library function, or vice versa.
+
+ PCRE_ERROR_BADENDIANNESS (-29)
+
+ This error is given if a pattern that was compiled and saved is
+ reloaded on a host with different endianness. The utility function
+ pcre_pattern_to_host_byte_order() can be used to convert such a pattern
+ so that it runs on the new host.
+
+ Error numbers -16 to -20, -22, and -30 are not used by pcre_exec().
+
+ Reason codes for invalid UTF-8 strings
+
+ This section applies only to the 8-bit library. The corresponding
+ information for the 16-bit library is given in the pcre16 page.
+
+ When pcre_exec() returns either PCRE_ERROR_BADUTF8 or PCRE_ERROR_SHORT-
+ UTF8, and the size of the output vector (ovecsize) is at least 2, the
+ offset of the start of the invalid UTF-8 character is placed in the
+ first output vector element (ovector[0]) and a reason code is placed in
+ the second element (ovector[1]). The reason codes are given names in
+ the pcre.h header file:
+
+ PCRE_UTF8_ERR1
+ PCRE_UTF8_ERR2
+ PCRE_UTF8_ERR3
+ PCRE_UTF8_ERR4
+ PCRE_UTF8_ERR5
+
+ The string ends with a truncated UTF-8 character; the code specifies
+ how many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8
+ characters to be no longer than 4 bytes, the encoding scheme (origi-
+ nally defined by RFC 2279) allows for up to 6 bytes, and this is
+ checked first; hence the possibility of 4 or 5 missing bytes.
+
+ PCRE_UTF8_ERR6
+ PCRE_UTF8_ERR7
+ PCRE_UTF8_ERR8
+ PCRE_UTF8_ERR9
+ PCRE_UTF8_ERR10
+
+ The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of
+ the character do not have the binary value 0b10 (that is, either the
+ most significant bit is 0, or the next bit is 1).
+
+ PCRE_UTF8_ERR11
+ PCRE_UTF8_ERR12
+
+ A character that is valid by the RFC 2279 rules is either 5 or 6 bytes
+ long; these code points are excluded by RFC 3629.
+
+ PCRE_UTF8_ERR13
+
+ A 4-byte character has a value greater than 0x10fff; these code points
+ are excluded by RFC 3629.
+
+ PCRE_UTF8_ERR14
+
+ A 3-byte character has a value in the range 0xd800 to 0xdfff; this
+ range of code points are reserved by RFC 3629 for use with UTF-16, and
+ so are excluded from UTF-8.
+
+ PCRE_UTF8_ERR15
+ PCRE_UTF8_ERR16
+ PCRE_UTF8_ERR17
+ PCRE_UTF8_ERR18
+ PCRE_UTF8_ERR19
+
+ A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes
+ for a value that can be represented by fewer bytes, which is invalid.
+ For example, the two bytes 0xc0, 0xae give the value 0x2e, whose cor-
+ rect coding uses just one byte.
+
+ PCRE_UTF8_ERR20
+
+ The two most significant bits of the first byte of a character have the
+ binary value 0b10 (that is, the most significant bit is 1 and the sec-
+ ond is 0). Such a byte can only validly occur as the second or subse-
+ quent byte of a multi-byte character.
- Error numbers -16 to -20 and -22 are not used by pcre_exec().
+ PCRE_UTF8_ERR21
+
+ The first byte of a character has the value 0xfe or 0xff. These values
+ can never occur in a valid UTF-8 string.
EXTRACTING CAPTURED SUBSTRINGS BY NUMBER
@@ -2512,78 +3097,78 @@
int pcre_get_substring_list(const char *subject,
int *ovector, int stringcount, const char ***listptr);
- Captured substrings can be accessed directly by using the offsets
- returned by pcre_exec() in ovector. For convenience, the functions
+ Captured substrings can be accessed directly by using the offsets
+ returned by pcre_exec() in ovector. For convenience, the functions
pcre_copy_substring(), pcre_get_substring(), and pcre_get_sub-
- string_list() are provided for extracting captured substrings as new,
- separate, zero-terminated strings. These functions identify substrings
- by number. The next section describes functions for extracting named
+ string_list() are provided for extracting captured substrings as new,
+ separate, zero-terminated strings. These functions identify substrings
+ by number. The next section describes functions for extracting named
substrings.
- A substring that contains a binary zero is correctly extracted and has
- a further zero added on the end, but the result is not, of course, a C
- string. However, you can process such a string by referring to the
- length that is returned by pcre_copy_substring() and pcre_get_sub-
+ A substring that contains a binary zero is correctly extracted and has
+ a further zero added on the end, but the result is not, of course, a C
+ string. However, you can process such a string by referring to the
+ length that is returned by pcre_copy_substring() and pcre_get_sub-
string(). Unfortunately, the interface to pcre_get_substring_list() is
- not adequate for handling strings containing binary zeros, because the
+ not adequate for handling strings containing binary zeros, because the
end of the final string is not independently indicated.
- The first three arguments are the same for all three of these func-
- tions: subject is the subject string that has just been successfully
+ The first three arguments are the same for all three of these func-
+ tions: subject is the subject string that has just been successfully
matched, ovector is a pointer to the vector of integer offsets that was
passed to pcre_exec(), and stringcount is the number of substrings that
- were captured by the match, including the substring that matched the
+ were captured by the match, including the substring that matched the
entire regular expression. This is the value returned by pcre_exec() if
- it is greater than zero. If pcre_exec() returned zero, indicating that
- it ran out of space in ovector, the value passed as stringcount should
+ it is greater than zero. If pcre_exec() returned zero, indicating that
+ it ran out of space in ovector, the value passed as stringcount should
be the number of elements in the vector divided by three.
- The functions pcre_copy_substring() and pcre_get_substring() extract a
- single substring, whose number is given as stringnumber. A value of
- zero extracts the substring that matched the entire pattern, whereas
- higher values extract the captured substrings. For pcre_copy_sub-
- string(), the string is placed in buffer, whose length is given by
- buffersize, while for pcre_get_substring() a new block of memory is
- obtained via pcre_malloc, and its address is returned via stringptr.
- The yield of the function is the length of the string, not including
+ The functions pcre_copy_substring() and pcre_get_substring() extract a
+ single substring, whose number is given as stringnumber. A value of
+ zero extracts the substring that matched the entire pattern, whereas
+ higher values extract the captured substrings. For pcre_copy_sub-
+ string(), the string is placed in buffer, whose length is given by
+ buffersize, while for pcre_get_substring() a new block of memory is
+ obtained via pcre_malloc, and its address is returned via stringptr.
+ The yield of the function is the length of the string, not including
the terminating zero, or one of these error codes:
PCRE_ERROR_NOMEMORY (-6)
- The buffer was too small for pcre_copy_substring(), or the attempt to
+ The buffer was too small for pcre_copy_substring(), or the attempt to
get memory failed for pcre_get_substring().
PCRE_ERROR_NOSUBSTRING (-7)
There is no substring whose number is stringnumber.
- The pcre_get_substring_list() function extracts all available sub-
- strings and builds a list of pointers to them. All this is done in a
+ The pcre_get_substring_list() function extracts all available sub-
+ strings and builds a list of pointers to them. All this is done in a
single block of memory that is obtained via pcre_malloc. The address of
- the memory block is returned via listptr, which is also the start of
- the list of string pointers. The end of the list is marked by a NULL
- pointer. The yield of the function is zero if all went well, or the
+ the memory block is returned via listptr, which is also the start of
+ the list of string pointers. The end of the list is marked by a NULL
+ pointer. The yield of the function is zero if all went well, or the
error code
PCRE_ERROR_NOMEMORY (-6)
if the attempt to get the memory block failed.
- When any of these functions encounter a substring that is unset, which
- can happen when capturing subpattern number n+1 matches some part of
- the subject, but subpattern n has not been used at all, they return an
+ When any of these functions encounter a substring that is unset, which
+ can happen when capturing subpattern number n+1 matches some part of
+ the subject, but subpattern n has not been used at all, they return an
empty string. This can be distinguished from a genuine zero-length sub-
- string by inspecting the appropriate offset in ovector, which is nega-
+ string by inspecting the appropriate offset in ovector, which is nega-
tive for unset substrings.
- The two convenience functions pcre_free_substring() and pcre_free_sub-
- string_list() can be used to free the memory returned by a previous
+ The two convenience functions pcre_free_substring() and pcre_free_sub-
+ string_list() can be used to free the memory returned by a previous
call of pcre_get_substring() or pcre_get_substring_list(), respec-
- tively. They do nothing more than call the function pointed to by
- pcre_free, which of course could be called directly from a C program.
- However, PCRE is used in some situations where it is linked via a spe-
- cial interface to another programming language that cannot use
- pcre_free directly; it is for these cases that the functions are pro-
+ tively. They do nothing more than call the function pointed to by
+ pcre_free, which of course could be called directly from a C program.
+ However, PCRE is used in some situations where it is linked via a spe-
+ cial interface to another programming language that cannot use
+ pcre_free directly; it is for these cases that the functions are pro-
vided.
@@ -2602,7 +3187,7 @@
int stringcount, const char *stringname,
const char **stringptr);
- To extract a substring by name, you first have to find associated num-
+ To extract a substring by name, you first have to find associated num-
ber. For example, for this pattern
(a+)b(?\d+)...
@@ -2611,35 +3196,35 @@
be unique (PCRE_DUPNAMES was not set), you can find the number from the
name by calling pcre_get_stringnumber(). The first argument is the com-
piled pattern, and the second is the name. The yield of the function is
- the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no
+ the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no
subpattern of that name.
Given the number, you can extract the substring directly, or use one of
the functions described in the previous section. For convenience, there
are also two functions that do the whole job.
- Most of the arguments of pcre_copy_named_substring() and
- pcre_get_named_substring() are the same as those for the similarly
- named functions that extract by number. As these are described in the
- previous section, they are not re-described here. There are just two
+ Most of the arguments of pcre_copy_named_substring() and
+ pcre_get_named_substring() are the same as those for the similarly
+ named functions that extract by number. As these are described in the
+ previous section, they are not re-described here. There are just two
differences:
- First, instead of a substring number, a substring name is given. Sec-
+ First, instead of a substring number, a substring name is given. Sec-
ond, there is an extra argument, given at the start, which is a pointer
- to the compiled pattern. This is needed in order to gain access to the
+ to the compiled pattern. This is needed in order to gain access to the
name-to-number translation table.
- These functions call pcre_get_stringnumber(), and if it succeeds, they
- then call pcre_copy_substring() or pcre_get_substring(), as appropri-
- ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the
+ These functions call pcre_get_stringnumber(), and if it succeeds, they
+ then call pcre_copy_substring() or pcre_get_substring(), as appropri-
+ ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the
behaviour may not be what you want (see the next section).
Warning: If the pattern uses the (?| feature to set up multiple subpat-
- terns with the same number, as described in the section on duplicate
- subpattern numbers in the pcrepattern page, you cannot use names to
- distinguish the different subpatterns, because names are not included
- in the compiled code. The matching process uses only numbers. For this
- reason, the use of different names for subpatterns of the same number
+ terns with the same number, as described in the section on duplicate
+ subpattern numbers in the pcrepattern page, you cannot use names to
+ distinguish the different subpatterns, because names are not included
+ in the compiled code. The matching process uses only numbers. For this
+ reason, the use of different names for subpatterns of the same number
causes an error at compile time.
@@ -2648,54 +3233,79 @@
int pcre_get_stringtable_entries(const pcre *code,
const char *name, char **first, char **last);
- When a pattern is compiled with the PCRE_DUPNAMES option, names for
- subpatterns are not required to be unique. (Duplicate names are always
- allowed for subpatterns with the same number, created by using the (?|
- feature. Indeed, if such subpatterns are named, they are required to
+ When a pattern is compiled with the PCRE_DUPNAMES option, names for
+ subpatterns are not required to be unique. (Duplicate names are always
+ allowed for subpatterns with the same number, created by using the (?|
+ feature. Indeed, if such subpatterns are named, they are required to
use the same names.)
Normally, patterns with duplicate names are such that in any one match,
- only one of the named subpatterns participates. An example is shown in
+ only one of the named subpatterns participates. An example is shown in
the pcrepattern documentation.
- When duplicates are present, pcre_copy_named_substring() and
- pcre_get_named_substring() return the first substring corresponding to
- the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING
- (-7) is returned; no data is returned. The pcre_get_stringnumber()
- function returns one of the numbers that are associated with the name,
+ When duplicates are present, pcre_copy_named_substring() and
+ pcre_get_named_substring() return the first substring corresponding to
+ the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING
+ (-7) is returned; no data is returned. The pcre_get_stringnumber()
+ function returns one of the numbers that are associated with the name,
but it is not defined which it is.
- If you want to get full details of all captured substrings for a given
- name, you must use the pcre_get_stringtable_entries() function. The
+ If you want to get full details of all captured substrings for a given
+ name, you must use the pcre_get_stringtable_entries() function. The
first argument is the compiled pattern, and the second is the name. The
- third and fourth are pointers to variables which are updated by the
+ third and fourth are pointers to variables which are updated by the
function. After it has run, they point to the first and last entries in
- the name-to-number table for the given name. The function itself
- returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if
- there are none. The format of the table is described above in the sec-
- tion entitled Information about a pattern. Given all the relevant
- entries for the name, you can extract each of their numbers, and hence
- the captured data, if any.
+ the name-to-number table for the given name. The function itself
+ returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if
+ there are none. The format of the table is described above in the sec-
+ tion entitled Information about a pattern above. Given all the rele-
+ vant entries for the name, you can extract each of their numbers, and
+ hence the captured data, if any.
FINDING ALL POSSIBLE MATCHES
- The traditional matching function uses a similar algorithm to Perl,
+ The traditional matching function uses a similar algorithm to Perl,
which stops when it finds the first match, starting at a given point in
- the subject. If you want to find all possible matches, or the longest
- possible match, consider using the alternative matching function (see
- below) instead. If you cannot use the alternative function, but still
- need to find all possible matches, you can kludge it up by making use
+ the subject. If you want to find all possible matches, or the longest
+ possible match, consider using the alternative matching function (see
+ below) instead. If you cannot use the alternative function, but still
+ need to find all possible matches, you can kludge it up by making use
of the callout facility, which is described in the pcrecallout documen-
tation.
What you have to do is to insert a callout right at the end of the pat-
- tern. When your callout function is called, extract and save the cur-
- rent matched substring. Then return 1, which forces pcre_exec() to
- backtrack and try other alternatives. Ultimately, when it runs out of
+ tern. When your callout function is called, extract and save the cur-
+ rent matched substring. Then return 1, which forces pcre_exec() to
+ backtrack and try other alternatives. Ultimately, when it runs out of
matches, pcre_exec() will yield PCRE_ERROR_NOMATCH.
+OBTAINING AN ESTIMATE OF STACK USAGE
+
+ Matching certain patterns using pcre_exec() can use a lot of process
+ stack, which in certain environments can be rather limited in size.
+ Some users find it helpful to have an estimate of the amount of stack
+ that is used by pcre_exec(), to help them set recursion limits, as
+ described in the pcrestack documentation. The estimate that is output
+ by pcretest when called with the -m and -C options is obtained by call-
+ ing pcre_exec with the values NULL, NULL, NULL, -999, and -999 for its
+ first five arguments.
+
+ Normally, if its first argument is NULL, pcre_exec() immediately
+ returns the negative error code PCRE_ERROR_NULL, but with this special
+ combination of arguments, it returns instead a negative number whose
+ absolute value is the approximate stack frame size in bytes. (A nega-
+ tive number is used so that it is clear that no match has happened.)
+ The value is approximate because in some cases, recursive calls to
+ pcre_exec() occur when there are one or two additional variables on the
+ stack.
+
+ If PCRE has been compiled to use the heap instead of the stack for
+ recursion, the value returned is the size of each block that is
+ obtained from the heap.
+
+
MATCHING A PATTERN: THE ALTERNATIVE FUNCTION
int pcre_dfa_exec(const pcre *code, const pcre_extra *extra,
@@ -2703,26 +3313,26 @@
int options, int *ovector, int ovecsize,
int *workspace, int wscount);
- The function pcre_dfa_exec() is called to match a subject string
- against a compiled pattern, using a matching algorithm that scans the
- subject string just once, and does not backtrack. This has different
- characteristics to the normal algorithm, and is not compatible with
- Perl. Some of the features of PCRE patterns are not supported. Never-
- theless, there are times when this kind of matching can be useful. For
- a discussion of the two matching algorithms, and a list of features
- that pcre_dfa_exec() does not support, see the pcrematching documenta-
+ The function pcre_dfa_exec() is called to match a subject string
+ against a compiled pattern, using a matching algorithm that scans the
+ subject string just once, and does not backtrack. This has different
+ characteristics to the normal algorithm, and is not compatible with
+ Perl. Some of the features of PCRE patterns are not supported. Never-
+ theless, there are times when this kind of matching can be useful. For
+ a discussion of the two matching algorithms, and a list of features
+ that pcre_dfa_exec() does not support, see the pcrematching documenta-
tion.
- The arguments for the pcre_dfa_exec() function are the same as for
+ The arguments for the pcre_dfa_exec() function are the same as for
pcre_exec(), plus two extras. The ovector argument is used in a differ-
- ent way, and this is described below. The other common arguments are
- used in the same way as for pcre_exec(), so their description is not
+ ent way, and this is described below. The other common arguments are
+ used in the same way as for pcre_exec(), so their description is not
repeated here.
- The two additional arguments provide workspace for the function. The
- workspace vector should contain at least 20 elements. It is used for
+ The two additional arguments provide workspace for the function. The
+ workspace vector should contain at least 20 elements. It is used for
keeping track of multiple paths through the pattern tree. More
- workspace will be needed for patterns and subjects where there are a
+ workspace will be needed for patterns and subjects where there are a
lot of potential matches.
Here is an example of a simple call to pcre_dfa_exec():
@@ -2744,55 +3354,55 @@
Option bits for pcre_dfa_exec()
- The unused bits of the options argument for pcre_dfa_exec() must be
- zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW-
+ The unused bits of the options argument for pcre_dfa_exec() must be
+ zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW-
LINE_xxx, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY,
- PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF,
- PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR-
- TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last
- four of these are exactly the same as for pcre_exec(), so their
+ PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF,
+ PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR-
+ TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last
+ four of these are exactly the same as for pcre_exec(), so their
description is not repeated here.
PCRE_PARTIAL_HARD
PCRE_PARTIAL_SOFT
- These have the same general effect as they do for pcre_exec(), but the
- details are slightly different. When PCRE_PARTIAL_HARD is set for
- pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub-
- ject is reached and there is still at least one matching possibility
+ These have the same general effect as they do for pcre_exec(), but the
+ details are slightly different. When PCRE_PARTIAL_HARD is set for
+ pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub-
+ ject is reached and there is still at least one matching possibility
that requires additional characters. This happens even if some complete
matches have also been found. When PCRE_PARTIAL_SOFT is set, the return
code PCRE_ERROR_NOMATCH is converted into PCRE_ERROR_PARTIAL if the end
- of the subject is reached, there have been no complete matches, but
- there is still at least one matching possibility. The portion of the
- string that was inspected when the longest partial match was found is
- set as the first matching string in both cases. There is a more
- detailed discussion of partial and multi-segment matching, with exam-
+ of the subject is reached, there have been no complete matches, but
+ there is still at least one matching possibility. The portion of the
+ string that was inspected when the longest partial match was found is
+ set as the first matching string in both cases. There is a more
+ detailed discussion of partial and multi-segment matching, with exam-
ples, in the pcrepartial documentation.
PCRE_DFA_SHORTEST
- Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to
+ Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to
stop as soon as it has found one match. Because of the way the alterna-
- tive algorithm works, this is necessarily the shortest possible match
+ tive algorithm works, this is necessarily the shortest possible match
at the first possible matching point in the subject string.
PCRE_DFA_RESTART
When pcre_dfa_exec() returns a partial match, it is possible to call it
- again, with additional subject characters, and have it continue with
- the same match. The PCRE_DFA_RESTART option requests this action; when
- it is set, the workspace and wscount options must reference the same
- vector as before because data about the match so far is left in them
+ again, with additional subject characters, and have it continue with
+ the same match. The PCRE_DFA_RESTART option requests this action; when
+ it is set, the workspace and wscount options must reference the same
+ vector as before because data about the match so far is left in them
after a partial match. There is more discussion of this facility in the
pcrepartial documentation.
Successful returns from pcre_dfa_exec()
- When pcre_dfa_exec() succeeds, it may have matched more than one sub-
+ When pcre_dfa_exec() succeeds, it may have matched more than one sub-
string in the subject. Note, however, that all the matches from one run
- of the function start at the same point in the subject. The shorter
- matches are all initial substrings of the longer matches. For example,
+ of the function start at the same point in the subject. The shorter
+ matches are all initial substrings of the longer matches. For example,
if the pattern
<.*>
@@ -2807,19 +3417,20 @@
- On success, the yield of the function is a number greater than zero,
- which is the number of matched substrings. The substrings themselves
- are returned in ovector. Each string uses two elements; the first is
- the offset to the start, and the second is the offset to the end. In
- fact, all the strings have the same start offset. (Space could have
- been saved by giving this only once, but it was decided to retain some
- compatibility with the way pcre_exec() returns data, even though the
+ On success, the yield of the function is a number greater than zero,
+ which is the number of matched substrings. The substrings themselves
+ are returned in ovector. Each string uses two elements; the first is
+ the offset to the start, and the second is the offset to the end. In
+ fact, all the strings have the same start offset. (Space could have
+ been saved by giving this only once, but it was decided to retain some
+ compatibility with the way pcre_exec() returns data, even though the
meaning of the strings is different.)
The strings are returned in reverse order of length; that is, the long-
- est matching string is given first. If there were too many matches to
- fit into ovector, the yield of the function is zero, and the vector is
- filled with the longest matches.
+ est matching string is given first. If there were too many matches to
+ fit into ovector, the yield of the function is zero, and the vector is
+ filled with the longest matches. Unlike pcre_exec(), pcre_dfa_exec()
+ can use the entire ovector for returning matched strings.
Error returns from pcre_dfa_exec()
@@ -2843,26 +3454,35 @@
PCRE_ERROR_DFA_UMLIMIT (-18)
This return is given if pcre_dfa_exec() is called with an extra block
- that contains a setting of the match_limit field. This is not supported
- (it is meaningless).
+ that contains a setting of the match_limit or match_limit_recursion
+ fields. This is not supported (these fields are meaningless for DFA
+ matching).
PCRE_ERROR_DFA_WSSIZE (-19)
- This return is given if pcre_dfa_exec() runs out of space in the
+ This return is given if pcre_dfa_exec() runs out of space in the
workspace vector.
PCRE_ERROR_DFA_RECURSE (-20)
- When a recursive subpattern is processed, the matching function calls
- itself recursively, using private vectors for ovector and workspace.
- This error is given if the output vector is not large enough. This
+ When a recursive subpattern is processed, the matching function calls
+ itself recursively, using private vectors for ovector and workspace.
+ This error is given if the output vector is not large enough. This
should be extremely rare, as a vector of size 1000 is used.
+ PCRE_ERROR_DFA_BADRESTART (-30)
+
+ When pcre_dfa_exec() is called with the PCRE_DFA_RESTART option, some
+ plausibility checks are made on the contents of the workspace, which
+ should contain data about the previous partial match. If any of these
+ checks fail, this error is given.
+
SEE ALSO
- pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), pcrematching(3), pcrepar-
- tial(3), pcreposix(3), pcreprecompile(3), pcresample(3), pcrestack(3).
+ pcre16(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), pcrematch-
+ ing(3), pcrepartial(3), pcreposix(3), pcreprecompile(3), pcresample(3),
+ pcrestack(3).
AUTHOR
@@ -2874,8 +3494,8 @@
REVISION
- Last updated: 21 November 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 17 June 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
@@ -2890,24 +3510,27 @@
int (*pcre_callout)(pcre_callout_block *);
+ int (*pcre16_callout)(pcre16_callout_block *);
+
PCRE provides a feature called "callout", which is a means of temporar-
ily passing control to the caller of PCRE in the middle of pattern
matching. The caller of PCRE provides an external function by putting
- its entry point in the global variable pcre_callout. By default, this
- variable contains NULL, which disables all calling out.
-
- Within a regular expression, (?C) indicates the points at which the
- external function is to be called. Different callout points can be
- identified by putting a number less than 256 after the letter C. The
- default value is zero. For example, this pattern has two callout
+ its entry point in the global variable pcre_callout (pcre16_callout for
+ the 16-bit library). By default, this variable contains NULL, which
+ disables all calling out.
+
+ Within a regular expression, (?C) indicates the points at which the
+ external function is to be called. Different callout points can be
+ identified by putting a number less than 256 after the letter C. The
+ default value is zero. For example, this pattern has two callout
points:
(?C1)abc(?C2)def
- If the PCRE_AUTO_CALLOUT option bit is set when pcre_compile() or
- pcre_compile2() is called, PCRE automatically inserts callouts, all
- with number 255, before each item in the pattern. For example, if
- PCRE_AUTO_CALLOUT is used with the pattern
+ If the PCRE_AUTO_CALLOUT option bit is set when a pattern is compiled,
+ PCRE automatically inserts callouts, all with number 255, before each
+ item in the pattern. For example, if PCRE_AUTO_CALLOUT is used with the
+ pattern
A(\d{2}|--)
@@ -2915,62 +3538,68 @@
(?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255)
- Notice that there is a callout before and after each parenthesis and
- alternation bar. Automatic callouts can be used for tracking the
- progress of pattern matching. The pcretest command has an option that
- sets automatic callouts; when it is used, the output indicates how the
- pattern is matched. This is useful information when you are trying to
+ Notice that there is a callout before and after each parenthesis and
+ alternation bar. Automatic callouts can be used for tracking the
+ progress of pattern matching. The pcretest command has an option that
+ sets automatic callouts; when it is used, the output indicates how the
+ pattern is matched. This is useful information when you are trying to
optimize the performance of a particular pattern.
+ The use of callouts in a pattern makes it ineligible for optimization
+ by the just-in-time compiler. Studying such a pattern with the
+ PCRE_STUDY_JIT_COMPILE option always fails.
+
MISSING CALLOUTS
- You should be aware that, because of optimizations in the way PCRE
- matches patterns by default, callouts sometimes do not happen. For
+ You should be aware that, because of optimizations in the way PCRE
+ matches patterns by default, callouts sometimes do not happen. For
example, if the pattern is
ab(?C4)cd
PCRE knows that any matching string must contain the letter "d". If the
- subject string is "abyz", the lack of "d" means that matching doesn't
- ever start, and the callout is never reached. However, with "abyd",
+ subject string is "abyz", the lack of "d" means that matching doesn't
+ ever start, and the callout is never reached. However, with "abyd",
though the result is still no match, the callout is obeyed.
- If the pattern is studied, PCRE knows the minimum length of a matching
- string, and will immediately give a "no match" return without actually
- running a match if the subject is not long enough, or, for unanchored
+ If the pattern is studied, PCRE knows the minimum length of a matching
+ string, and will immediately give a "no match" return without actually
+ running a match if the subject is not long enough, or, for unanchored
patterns, if it has been scanned far enough.
- You can disable these optimizations by passing the PCRE_NO_START_OPTI-
- MIZE option to pcre_compile(), pcre_exec(), or pcre_dfa_exec(), or by
- starting the pattern with (*NO_START_OPT). This slows down the matching
- process, but does ensure that callouts such as the example above are
- obeyed.
+ You can disable these optimizations by passing the PCRE_NO_START_OPTI-
+ MIZE option to the matching function, or by starting the pattern with
+ (*NO_START_OPT). This slows down the matching process, but does ensure
+ that callouts such as the example above are obeyed.
THE CALLOUT INTERFACE
During matching, when PCRE reaches a callout point, the external func-
- tion defined by pcre_callout is called (if it is set). This applies to
- both the pcre_exec() and the pcre_dfa_exec() matching functions. The
- only argument to the callout function is a pointer to a pcre_callout
- block. This structure contains the following fields:
-
- int version;
- int callout_number;
- int *offset_vector;
- const char *subject;
- int subject_length;
- int start_match;
- int current_position;
- int capture_top;
- int capture_last;
- void *callout_data;
- int pattern_position;
- int next_item_length;
+ tion defined by pcre_callout or pcre16_callout is called (if it is
+ set). This applies to both normal and DFA matching. The only argument
+ to the callout function is a pointer to a pcre_callout or pcre16_call-
+ out block. These structures contains the following fields:
+
+ int version;
+ int callout_number;
+ int *offset_vector;
+ const char *subject; (8-bit version)
+ PCRE_SPTR16 subject; (16-bit version)
+ int subject_length;
+ int start_match;
+ int current_position;
+ int capture_top;
+ int capture_last;
+ void *callout_data;
+ int pattern_position;
+ int next_item_length;
+ const unsigned char *mark; (8-bit version)
+ const PCRE_UCHAR16 *mark; (16-bit version)
The version field is an integer containing the version number of the
- block format. The initial version was 0; the current version is 1. The
+ block format. The initial version was 0; the current version is 2. The
version number will change again in future if additional fields are
added, but the intention is never to remove any of the existing fields.
@@ -2979,14 +3608,14 @@
outs, and 255 for automatically generated callouts).
The offset_vector field is a pointer to the vector of offsets that was
- passed by the caller to pcre_exec() or pcre_dfa_exec(). When
- pcre_exec() is used, the contents can be inspected in order to extract
- substrings that have been matched so far, in the same way as for
- extracting substrings after a match has completed. For pcre_dfa_exec()
- this field is not useful.
+ passed by the caller to the matching function. When pcre_exec() or
+ pcre16_exec() is used, the contents can be inspected, in order to
+ extract substrings that have been matched so far, in the same way as
+ for extracting substrings after a match has completed. For the DFA
+ matching functions, this field is not useful.
The subject and subject_length fields contain copies of the values that
- were passed to pcre_exec().
+ were passed to the matching function.
The start_match field normally contains the offset within the subject
at which the current match attempt started. However, if the escape
@@ -2998,38 +3627,46 @@
The current_position field contains the offset within the subject of
the current match pointer.
- When the pcre_exec() function is used, the capture_top field contains
- one more than the number of the highest numbered captured substring so
- far. If no substrings have been captured, the value of capture_top is
- one. This is always the case when pcre_dfa_exec() is used, because it
- does not support captured substrings.
+ When the pcre_exec() or pcre16_exec() is used, the capture_top field
+ contains one more than the number of the highest numbered captured sub-
+ string so far. If no substrings have been captured, the value of cap-
+ ture_top is one. This is always the case when the DFA functions are
+ used, because they do not support captured substrings.
The capture_last field contains the number of the most recently cap-
tured substring. If no substrings have been captured, its value is -1.
- This is always the case when pcre_dfa_exec() is used.
+ This is always the case for the DFA matching functions.
- The callout_data field contains a value that is passed to pcre_exec()
- or pcre_dfa_exec() specifically so that it can be passed back in call-
- outs. It is passed in the pcre_callout field of the pcre_extra data
+ The callout_data field contains a value that is passed to a matching
+ function specifically so that it can be passed back in callouts. It is
+ passed in the callout_data field of a pcre_extra or pcre16_extra data
structure. If no such data was passed, the value of callout_data in a
- pcre_callout block is NULL. There is a description of the pcre_extra
- structure in the pcreapi documentation.
+ callout block is NULL. There is a description of the pcre_extra struc-
+ ture in the pcreapi documentation.
- The pattern_position field is present from version 1 of the pcre_call-
- out structure. It contains the offset to the next item to be matched in
- the pattern string.
-
- The next_item_length field is present from version 1 of the pcre_call-
- out structure. It contains the length of the next item to be matched in
- the pattern string. When the callout immediately precedes an alterna-
- tion bar, a closing parenthesis, or the end of the pattern, the length
- is zero. When the callout precedes an opening parenthesis, the length
- is that of the entire subpattern.
+ The pattern_position field is present from version 1 of the callout
+ structure. It contains the offset to the next item to be matched in the
+ pattern string.
+
+ The next_item_length field is present from version 1 of the callout
+ structure. It contains the length of the next item to be matched in the
+ pattern string. When the callout immediately precedes an alternation
+ bar, a closing parenthesis, or the end of the pattern, the length is
+ zero. When the callout precedes an opening parenthesis, the length is
+ that of the entire subpattern.
The pattern_position and next_item_length fields are intended to help
in distinguishing between different automatic callouts, which all have
the same callout number. However, they are set for all callouts.
+ The mark field is present from version 2 of the callout structure. In
+ callouts from pcre_exec() or pcre16_exec() it contains a pointer to the
+ zero-terminated name of the most recently passed (*MARK), (*PRUNE), or
+ (*THEN) item in the match, or NULL if no such items have been passed.
+ Instances of (*PRUNE) or (*THEN) without a name do not obliterate a
+ previous (*MARK). In callouts from the DFA matching functions this
+ field always contains NULL.
+
RETURN VALUES
@@ -3037,8 +3674,8 @@
is zero, matching proceeds as normal. If the value is greater than
zero, matching fails at the current point, but the testing of other
matching possibilities goes ahead, just as if a lookahead assertion had
- failed. If the value is less than zero, the match is abandoned, and
- pcre_exec() or pcre_dfa_exec() returns the negative value.
+ failed. If the value is less than zero, the match is abandoned, the
+ matching function returns the negative value.
Negative values should normally be chosen from the set of
PCRE_ERROR_xxx values. In particular, PCRE_ERROR_NOMATCH forces a stan-
@@ -3056,8 +3693,8 @@
REVISION
- Last updated: 21 November 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 08 Janurary 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
@@ -3074,43 +3711,53 @@
handle regular expressions. The differences described here are with
respect to Perl versions 5.10 and above.
- 1. PCRE has only a subset of Perl's UTF-8 and Unicode support. Details
- of what it does have are given in the section on UTF-8 support in the
- main pcre page.
-
- 2. PCRE does not allow repeat quantifiers on lookahead assertions. Perl
- permits them, but they do not mean what you might think. For example,
- (?!a){3} does not assert that the next three characters are not "a". It
- just asserts that the next character is not "a" three times.
-
- 3. Capturing subpatterns that occur inside negative lookahead asser-
- tions are counted, but their entries in the offsets vector are never
- set. Perl sets its numerical variables from any such patterns that are
+ 1. PCRE has only a subset of Perl's Unicode support. Details of what it
+ does have are given in the pcreunicode page.
+
+ 2. PCRE allows repeat quantifiers only on parenthesized assertions, but
+ they do not mean what you might think. For example, (?!a){3} does not
+ assert that the next three characters are not "a". It just asserts that
+ the next character is not "a" three times (in principle: PCRE optimizes
+ this to run the assertion just once). Perl allows repeat quantifiers on
+ other assertions such as \b, but these do not seem to have any use.
+
+ 3. Capturing subpatterns that occur inside negative lookahead asser-
+ tions are counted, but their entries in the offsets vector are never
+ set. Perl sets its numerical variables from any such patterns that are
matched before the assertion fails to match something (thereby succeed-
- ing), but only if the negative lookahead assertion contains just one
+ ing), but only if the negative lookahead assertion contains just one
branch.
- 4. Though binary zero characters are supported in the subject string,
+ 4. Though binary zero characters are supported in the subject string,
they are not allowed in a pattern string because it is passed as a nor-
mal C string, terminated by zero. The escape sequence \0 can be used in
the pattern to represent a binary zero.
- 5. The following Perl escape sequences are not supported: \l, \u, \L,
- \U, and \N. In fact these are implemented by Perl's general string-han-
- dling and are not part of its pattern matching engine. If any of these
- are encountered by PCRE, an error is generated.
-
- 6. The Perl escape sequences \p, \P, and \X are supported only if PCRE
- is built with Unicode character property support. The properties that
- can be tested with \p and \P are limited to the general category prop-
- erties such as Lu and Nd, script names such as Greek or Han, and the
- derived properties Any and L&. PCRE does support the Cs (surrogate)
- property, which Perl does not; the Perl documentation says "Because
+ 5. The following Perl escape sequences are not supported: \l, \u, \L,
+ \U, and \N when followed by a character name or Unicode value. (\N on
+ its own, matching a non-newline character, is supported.) In fact these
+ are implemented by Perl's general string-handling and are not part of
+ its pattern matching engine. If any of these are encountered by PCRE,
+ an error is generated by default. However, if the PCRE_JAVASCRIPT_COM-
+ PAT option is set, \U and \u are interpreted as JavaScript interprets
+ them.
+
+ 6. The Perl escape sequences \p, \P, and \X are supported only if PCRE
+ is built with Unicode character property support. The properties that
+ can be tested with \p and \P are limited to the general category prop-
+ erties such as Lu and Nd, script names such as Greek or Han, and the
+ derived properties Any and L&. PCRE does support the Cs (surrogate)
+ property, which Perl does not; the Perl documentation says "Because
Perl hides the need for the user to understand the internal representa-
- tion of Unicode characters, there is no need to implement the somewhat
+ tion of Unicode characters, there is no need to implement the somewhat
messy concept of surrogates."
- 7. PCRE does support the \Q...\E escape for quoting substrings. Charac-
+ 7. PCRE implements a simpler version of \X than Perl, which changed to
+ make \X match what Unicode calls an "extended grapheme cluster". This
+ is more complicated than an extended Unicode sequence, which is what
+ PCRE matches.
+
+ 8. PCRE does support the \Q...\E escape for quoting substrings. Charac-
ters in between are treated as literals. This is slightly different
from Perl in that $ and @ are also handled as literals inside the
quotes. In Perl, they cause variable interpolation (but of course PCRE
@@ -3126,55 +3773,70 @@
The \Q...\E sequence is recognized both inside and outside character
classes.
- 8. Fairly obviously, PCRE does not support the (?{code}) and (??{code})
+ 9. Fairly obviously, PCRE does not support the (?{code}) and (??{code})
constructions. However, there is support for recursive patterns. This
is not available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE
"callout" feature allows an external function to be called during pat-
tern matching. See the pcrecallout documentation for details.
- 9. Subpatterns that are called recursively or as "subroutines" are
- always treated as atomic groups in PCRE. This is like Python, but
- unlike Perl. There is a discussion of an example that explains this in
- more detail in the section on recursion differences from Perl in the
- pcrepattern page.
-
- 10. There are some differences that are concerned with the settings of
- captured strings when part of a pattern is repeated. For example,
- matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2
+ 10. Subpatterns that are called as subroutines (whether or not recur-
+ sively) are always treated as atomic groups in PCRE. This is like
+ Python, but unlike Perl. Captured values that are set outside a sub-
+ routine call can be reference from inside in PCRE, but not in Perl.
+ There is a discussion that explains these differences in more detail in
+ the section on recursion differences from Perl in the pcrepattern page.
+
+ 11. If any of the backtracking control verbs are used in an assertion
+ or in a subpattern that is called as a subroutine (whether or not
+ recursively), their effect is confined to that subpattern; it does not
+ extend to the surrounding pattern. This is not always the case in Perl.
+ In particular, if (*THEN) is present in a group that is called as a
+ subroutine, its action is limited to that group, even if the group does
+ not contain any | characters. There is one exception to this: the name
+ from a *(MARK), (*PRUNE), or (*THEN) that is encountered in a success-
+ ful positive assertion is passed back when a match succeeds (compare
+ capturing parentheses in assertions). Note that such subpatterns are
+ processed as anchored at the point where they are tested.
+
+ 12. There are some differences that are concerned with the settings of
+ captured strings when part of a pattern is repeated. For example,
+ matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2
unset, but in PCRE it is set to "b".
- 11. PCRE's handling of duplicate subpattern numbers and duplicate sub-
+ 13. PCRE's handling of duplicate subpattern numbers and duplicate sub-
pattern names is not as general as Perl's. This is a consequence of the
fact the PCRE works internally just with numbers, using an external ta-
- ble to translate between numbers and names. In particular, a pattern
- such as (?|(?A)|(?A)|(?\r\n|\n|\x0b|\f|\r|\x85)
This is an example of an "atomic group", details of which are given
below. This particular group matches either the two-character sequence
CR followed by LF, or one of the single characters LF (linefeed,
- U+000A), VT (vertical tab, U+000B), FF (formfeed, U+000C), CR (carriage
- return, U+000D), or NEL (next line, U+0085). The two-character sequence
- is treated as a single unit that cannot be split.
+ U+000A), VT (vertical tab, U+000B), FF (form feed, U+000C), CR (car-
+ riage return, U+000D), or NEL (next line, U+0085). The two-character
+ sequence is treated as a single unit that cannot be split.
- In UTF-8 mode, two additional characters whose codepoints are greater
+ In other modes, two additional characters whose codepoints are greater
than 255 are added: LS (line separator, U+2028) and PS (paragraph sepa-
rator, U+2029). Unicode character property support is not needed for
these characters to be recognized.
@@ -3656,28 +4357,28 @@
(*BSR_ANYCRLF) CR, LF, or CRLF only
(*BSR_UNICODE) any Unicode newline sequence
- These override the default and the options given to pcre_compile() or
- pcre_compile2(), but they can be overridden by options given to
- pcre_exec() or pcre_dfa_exec(). Note that these special settings, which
- are not Perl-compatible, are recognized only at the very start of a
- pattern, and that they must be in upper case. If more than one of them
- is present, the last one is used. They can be combined with a change of
+ These override the default and the options given to the compiling func-
+ tion, but they can themselves be overridden by options given to a
+ matching function. Note that these special settings, which are not
+ Perl-compatible, are recognized only at the very start of a pattern,
+ and that they must be in upper case. If more than one of them is
+ present, the last one is used. They can be combined with a change of
newline convention; for example, a pattern can start with:
(*ANY)(*BSR_ANYCRLF)
- They can also be combined with the (*UTF8) or (*UCP) special sequences.
- Inside a character class, \R is treated as an unrecognized escape
- sequence, and so matches the letter "R" by default, but causes an error
- if PCRE_EXTRA is set.
+ They can also be combined with the (*UTF8), (*UTF16), or (*UCP) special
+ sequences. Inside a character class, \R is treated as an unrecognized
+ escape sequence, and so matches the letter "R" by default, but causes
+ an error if PCRE_EXTRA is set.
Unicode character properties
When PCRE is built with Unicode character property support, three addi-
tional escape sequences that match characters with specific properties
- are available. When not in UTF-8 mode, these sequences are of course
- limited to testing characters whose codepoints are less than 256, but
- they do work in this mode. The extra escape sequences are:
+ are available. When in 8-bit non-UTF-8 mode, these sequences are of
+ course limited to testing characters whose codepoints are less than
+ 256, but they do work in this mode. The extra escape sequences are:
\p{xx} a character with the xx property
\P{xx} a character without the xx property
@@ -3700,20 +4401,22 @@
Those that are not part of an identified script are lumped together as
"Common". The current list of scripts is:
- Arabic, Armenian, Avestan, Balinese, Bamum, Bengali, Bopomofo, Braille,
- Buginese, Buhid, Canadian_Aboriginal, Carian, Cham, Cherokee, Common,
- Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyp-
- tian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek,
- Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Impe-
- rial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscriptional_Parthian,
- Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao,
- Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam,
- Meetei_Mayek, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic,
- Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya,
- Phags_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Shavian,
- Sinhala, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le,
- Tai_Tham, Tai_Viet, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh,
- Ugaritic, Vai, Yi.
+ Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo,
+ Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma,
+ Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret,
+ Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic,
+ Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hira-
+ gana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip-
+ tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li,
+ Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian,
+ Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive,
+ Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko,
+ Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic,
+ Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samari-
+ tan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese,
+ Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet,
+ Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai,
+ Yi.
Each character has exactly one Unicode general category property, spec-
ified by a two-letter abbreviation. For compatibility with Perl, nega-
@@ -3780,45 +4483,50 @@
classified as a modifier or "other".
The Cs (Surrogate) property applies only to characters in the range
- U+D800 to U+DFFF. Such characters are not valid in UTF-8 strings (see
- RFC 3629) and so cannot be tested by PCRE, unless UTF-8 validity check-
- ing has been turned off (see the discussion of PCRE_NO_UTF8_CHECK in
- the pcreapi page). Perl does not support the Cs property.
+ U+D800 to U+DFFF. Such characters are not valid in Unicode strings and
+ so cannot be tested by PCRE, unless UTF validity checking has been
+ turned off (see the discussion of PCRE_NO_UTF8_CHECK and
+ PCRE_NO_UTF16_CHECK in the pcreapi page). Perl does not support the Cs
+ property.
- The long synonyms for property names that Perl supports (such as
- \p{Letter}) are not supported by PCRE, nor is it permitted to prefix
+ The long synonyms for property names that Perl supports (such as
+ \p{Letter}) are not supported by PCRE, nor is it permitted to prefix
any of these properties with "Is".
No character that is in the Unicode table has the Cn (unassigned) prop-
erty. Instead, this property is assumed for any code point that is not
in the Unicode table.
- Specifying caseless matching does not affect these escape sequences.
+ Specifying caseless matching does not affect these escape sequences.
For example, \p{Lu} always matches only upper case letters.
- The \X escape matches any number of Unicode characters that form an
+ The \X escape matches any number of Unicode characters that form an
extended Unicode sequence. \X is equivalent to
(?>\PM\pM*)
- That is, it matches a character without the "mark" property, followed
- by zero or more characters with the "mark" property, and treats the
- sequence as an atomic group (see below). Characters with the "mark"
- property are typically accents that affect the preceding character.
- None of them have codepoints less than 256, so in non-UTF-8 mode \X
- matches any one character.
+ That is, it matches a character without the "mark" property, followed
+ by zero or more characters with the "mark" property, and treats the
+ sequence as an atomic group (see below). Characters with the "mark"
+ property are typically accents that affect the preceding character.
+ None of them have codepoints less than 256, so in 8-bit non-UTF-8 mode
+ \X matches any one character.
+
+ Note that recent versions of Perl have changed \X to match what Unicode
+ calls an "extended grapheme cluster", which has a more complicated def-
+ inition.
- Matching characters by Unicode property is not fast, because PCRE has
- to search a structure that contains data for over fifteen thousand
+ Matching characters by Unicode property is not fast, because PCRE has
+ to search a structure that contains data for over fifteen thousand
characters. That is why the traditional escape sequences such as \d and
- \w do not use Unicode properties in PCRE by default, though you can
- make them do so by setting the PCRE_UCP option for pcre_compile() or by
- starting the pattern with (*UCP).
+ \w do not use Unicode properties in PCRE by default, though you can
+ make them do so by setting the PCRE_UCP option or by starting the pat-
+ tern with (*UCP).
PCRE's additional properties
- As well as the standard Unicode properties described in the previous
- section, PCRE supports four more that make it possible to convert tra-
+ As well as the standard Unicode properties described in the previous
+ section, PCRE supports four more that make it possible to convert tra-
ditional escape sequences such as \w and \s and POSIX character classes
to use Unicode properties. PCRE uses these non-standard, non-Perl prop-
erties internally when PCRE_UCP is set. They are:
@@ -3828,40 +4536,40 @@
Xsp Any Perl space character
Xwd Any Perl "word" character
- Xan matches characters that have either the L (letter) or the N (num-
- ber) property. Xps matches the characters tab, linefeed, vertical tab,
- formfeed, or carriage return, and any other character that has the Z
+ Xan matches characters that have either the L (letter) or the N (num-
+ ber) property. Xps matches the characters tab, linefeed, vertical tab,
+ form feed, or carriage return, and any other character that has the Z
(separator) property. Xsp is the same as Xps, except that vertical tab
is excluded. Xwd matches the same characters as Xan, plus underscore.
Resetting the match start
- The escape sequence \K causes any previously matched characters not to
+ The escape sequence \K causes any previously matched characters not to
be included in the final matched sequence. For example, the pattern:
foo\Kbar
- matches "foobar", but reports that it has matched "bar". This feature
- is similar to a lookbehind assertion (described below). However, in
- this case, the part of the subject before the real match does not have
- to be of fixed length, as lookbehind assertions do. The use of \K does
- not interfere with the setting of captured substrings. For example,
+ matches "foobar", but reports that it has matched "bar". This feature
+ is similar to a lookbehind assertion (described below). However, in
+ this case, the part of the subject before the real match does not have
+ to be of fixed length, as lookbehind assertions do. The use of \K does
+ not interfere with the setting of captured substrings. For example,
when the pattern
(foo)\Kbar
matches "foobar", the first substring is still set to "foo".
- Perl documents that the use of \K within assertions is "not well
- defined". In PCRE, \K is acted upon when it occurs inside positive
+ Perl documents that the use of \K within assertions is "not well
+ defined". In PCRE, \K is acted upon when it occurs inside positive
assertions, but is ignored in negative assertions.
Simple assertions
- The final use of backslash is for certain simple assertions. An asser-
- tion specifies a condition that has to be met at a particular point in
- a match, without consuming any characters from the subject string. The
- use of subpatterns for more complicated assertions is described below.
+ The final use of backslash is for certain simple assertions. An asser-
+ tion specifies a condition that has to be met at a particular point in
+ a match, without consuming any characters from the subject string. The
+ use of subpatterns for more complicated assertions is described below.
The backslashed assertions are:
\b matches at a word boundary
@@ -3872,49 +4580,49 @@
\z matches only at the end of the subject
\G matches at the first matching position in the subject
- Inside a character class, \b has a different meaning; it matches the
- backspace character. If any other of these assertions appears in a
- character class, by default it matches the corresponding literal char-
+ Inside a character class, \b has a different meaning; it matches the
+ backspace character. If any other of these assertions appears in a
+ character class, by default it matches the corresponding literal char-
acter (for example, \B matches the letter B). However, if the
- PCRE_EXTRA option is set, an "invalid escape sequence" error is gener-
+ PCRE_EXTRA option is set, an "invalid escape sequence" error is gener-
ated instead.
- A word boundary is a position in the subject string where the current
- character and the previous character do not both match \w or \W (i.e.
- one matches \w and the other matches \W), or the start or end of the
- string if the first or last character matches \w, respectively. In
- UTF-8 mode, the meanings of \w and \W can be changed by setting the
- PCRE_UCP option. When this is done, it also affects \b and \B. Neither
- PCRE nor Perl has a separate "start of word" or "end of word" metase-
- quence. However, whatever follows \b normally determines which it is.
+ A word boundary is a position in the subject string where the current
+ character and the previous character do not both match \w or \W (i.e.
+ one matches \w and the other matches \W), or the start or end of the
+ string if the first or last character matches \w, respectively. In a
+ UTF mode, the meanings of \w and \W can be changed by setting the
+ PCRE_UCP option. When this is done, it also affects \b and \B. Neither
+ PCRE nor Perl has a separate "start of word" or "end of word" metase-
+ quence. However, whatever follows \b normally determines which it is.
For example, the fragment \ba matches "a" at the start of a word.
- The \A, \Z, and \z assertions differ from the traditional circumflex
+ The \A, \Z, and \z assertions differ from the traditional circumflex
and dollar (described in the next section) in that they only ever match
- at the very start and end of the subject string, whatever options are
- set. Thus, they are independent of multiline mode. These three asser-
+ at the very start and end of the subject string, whatever options are
+ set. Thus, they are independent of multiline mode. These three asser-
tions are not affected by the PCRE_NOTBOL or PCRE_NOTEOL options, which
- affect only the behaviour of the circumflex and dollar metacharacters.
- However, if the startoffset argument of pcre_exec() is non-zero, indi-
+ affect only the behaviour of the circumflex and dollar metacharacters.
+ However, if the startoffset argument of pcre_exec() is non-zero, indi-
cating that matching is to start at a point other than the beginning of
- the subject, \A can never match. The difference between \Z and \z is
+ the subject, \A can never match. The difference between \Z and \z is
that \Z matches before a newline at the end of the string as well as at
the very end, whereas \z matches only at the end.
- The \G assertion is true only when the current matching position is at
- the start point of the match, as specified by the startoffset argument
- of pcre_exec(). It differs from \A when the value of startoffset is
- non-zero. By calling pcre_exec() multiple times with appropriate argu-
+ The \G assertion is true only when the current matching position is at
+ the start point of the match, as specified by the startoffset argument
+ of pcre_exec(). It differs from \A when the value of startoffset is
+ non-zero. By calling pcre_exec() multiple times with appropriate argu-
ments, you can mimic Perl's /g option, and it is in this kind of imple-
mentation where \G can be useful.
- Note, however, that PCRE's interpretation of \G, as the start of the
+ Note, however, that PCRE's interpretation of \G, as the start of the
current match, is subtly different from Perl's, which defines it as the
- end of the previous match. In Perl, these can be different when the
- previously matched string was empty. Because PCRE does just one match
+ end of the previous match. In Perl, these can be different when the
+ previously matched string was empty. Because PCRE does just one match
at a time, it cannot reproduce this behaviour.
- If all the alternatives of a pattern begin with \G, the expression is
+ If all the alternatives of a pattern begin with \G, the expression is
anchored to the starting match position, and the "anchored" flag is set
in the compiled regular expression.
@@ -3922,60 +4630,59 @@
CIRCUMFLEX AND DOLLAR
Outside a character class, in the default matching mode, the circumflex
- character is an assertion that is true only if the current matching
- point is at the start of the subject string. If the startoffset argu-
- ment of pcre_exec() is non-zero, circumflex can never match if the
- PCRE_MULTILINE option is unset. Inside a character class, circumflex
+ character is an assertion that is true only if the current matching
+ point is at the start of the subject string. If the startoffset argu-
+ ment of pcre_exec() is non-zero, circumflex can never match if the
+ PCRE_MULTILINE option is unset. Inside a character class, circumflex
has an entirely different meaning (see below).
- Circumflex need not be the first character of the pattern if a number
- of alternatives are involved, but it should be the first thing in each
- alternative in which it appears if the pattern is ever to match that
- branch. If all possible alternatives start with a circumflex, that is,
- if the pattern is constrained to match only at the start of the sub-
- ject, it is said to be an "anchored" pattern. (There are also other
+ Circumflex need not be the first character of the pattern if a number
+ of alternatives are involved, but it should be the first thing in each
+ alternative in which it appears if the pattern is ever to match that
+ branch. If all possible alternatives start with a circumflex, that is,
+ if the pattern is constrained to match only at the start of the sub-
+ ject, it is said to be an "anchored" pattern. (There are also other
constructs that can cause a pattern to be anchored.)
- A dollar character is an assertion that is true only if the current
- matching point is at the end of the subject string, or immediately
+ A dollar character is an assertion that is true only if the current
+ matching point is at the end of the subject string, or immediately
before a newline at the end of the string (by default). Dollar need not
- be the last character of the pattern if a number of alternatives are
- involved, but it should be the last item in any branch in which it
+ be the last character of the pattern if a number of alternatives are
+ involved, but it should be the last item in any branch in which it
appears. Dollar has no special meaning in a character class.
- The meaning of dollar can be changed so that it matches only at the
- very end of the string, by setting the PCRE_DOLLAR_ENDONLY option at
+ The meaning of dollar can be changed so that it matches only at the
+ very end of the string, by setting the PCRE_DOLLAR_ENDONLY option at
compile time. This does not affect the \Z assertion.
The meanings of the circumflex and dollar characters are changed if the
- PCRE_MULTILINE option is set. When this is the case, a circumflex
- matches immediately after internal newlines as well as at the start of
- the subject string. It does not match after a newline that ends the
- string. A dollar matches before any newlines in the string, as well as
- at the very end, when PCRE_MULTILINE is set. When newline is specified
- as the two-character sequence CRLF, isolated CR and LF characters do
+ PCRE_MULTILINE option is set. When this is the case, a circumflex
+ matches immediately after internal newlines as well as at the start of
+ the subject string. It does not match after a newline that ends the
+ string. A dollar matches before any newlines in the string, as well as
+ at the very end, when PCRE_MULTILINE is set. When newline is specified
+ as the two-character sequence CRLF, isolated CR and LF characters do
not indicate newlines.
- For example, the pattern /^abc$/ matches the subject string "def\nabc"
- (where \n represents a newline) in multiline mode, but not otherwise.
- Consequently, patterns that are anchored in single line mode because
- all branches start with ^ are not anchored in multiline mode, and a
- match for circumflex is possible when the startoffset argument of
- pcre_exec() is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if
+ For example, the pattern /^abc$/ matches the subject string "def\nabc"
+ (where \n represents a newline) in multiline mode, but not otherwise.
+ Consequently, patterns that are anchored in single line mode because
+ all branches start with ^ are not anchored in multiline mode, and a
+ match for circumflex is possible when the startoffset argument of
+ pcre_exec() is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if
PCRE_MULTILINE is set.
- Note that the sequences \A, \Z, and \z can be used to match the start
- and end of the subject in both modes, and if all branches of a pattern
- start with \A it is always anchored, whether or not PCRE_MULTILINE is
+ Note that the sequences \A, \Z, and \z can be used to match the start
+ and end of the subject in both modes, and if all branches of a pattern
+ start with \A it is always anchored, whether or not PCRE_MULTILINE is
set.
FULL STOP (PERIOD, DOT) AND \N
Outside a character class, a dot in the pattern matches any one charac-
- ter in the subject string except (by default) a character that signi-
- fies the end of a line. In UTF-8 mode, the matched character may be
- more than one byte long.
+ ter in the subject string except (by default) a character that signi-
+ fies the end of a line.
When a line ending is defined as a single character, dot never matches
that character; when the two-character sequence CRLF is used, dot does
@@ -3995,23 +4702,47 @@
The escape sequence \N behaves like a dot, except that it is not
affected by the PCRE_DOTALL option. In other words, it matches any
- character except one that signifies the end of a line.
+ character except one that signifies the end of a line. Perl also uses
+ \N to match characters by name; PCRE does not support this.
-MATCHING A SINGLE BYTE
+MATCHING A SINGLE DATA UNIT
- Outside a character class, the escape sequence \C matches any one byte,
- both in and out of UTF-8 mode. Unlike a dot, it always matches any
- line-ending characters. The feature is provided in Perl in order to
- match individual bytes in UTF-8 mode. Because it breaks up UTF-8 char-
- acters into individual bytes, the rest of the string may start with a
- malformed UTF-8 character. For this reason, the \C escape sequence is
- best avoided.
+ Outside a character class, the escape sequence \C matches any one data
+ unit, whether or not a UTF mode is set. In the 8-bit library, one data
+ unit is one byte; in the 16-bit library it is a 16-bit unit. Unlike a
+ dot, \C always matches line-ending characters. The feature is provided
+ in Perl in order to match individual bytes in UTF-8 mode, but it is
+ unclear how it can usefully be used. Because \C breaks up characters
+ into individual data units, matching one unit with \C in a UTF mode
+ means that the rest of the string may start with a malformed UTF char-
+ acter. This has undefined results, because PCRE assumes that it is
+ dealing with valid UTF strings (and by default it checks this at the
+ start of processing unless the PCRE_NO_UTF8_CHECK or
+ PCRE_NO_UTF16_CHECK option is used).
PCRE does not allow \C to appear in lookbehind assertions (described
- below), because in UTF-8 mode this would make it impossible to calcu-
+ below) in a UTF mode, because this would make it impossible to calcu-
late the length of the lookbehind.
+ In general, the \C escape sequence is best avoided. However, one way of
+ using it that avoids the problem of malformed UTF characters is to use
+ a lookahead to check the length of the next character, as in this pat-
+ tern, which could be used with a UTF-8 string (ignore white space and
+ line breaks):
+
+ (?| (?=[\x00-\x7f])(\C) |
+ (?=[\x80-\x{7ff}])(\C)(\C) |
+ (?=[\x{800}-\x{ffff}])(\C)(\C)(\C) |
+ (?=[\x{10000}-\x{1fffff}])(\C)(\C)(\C)(\C))
+
+ A group that starts with (?| resets the capturing parentheses numbers
+ in each alternative (see "Duplicate Subpattern Numbers" below). The
+ assertions at the start of each branch check the next UTF-8 character
+ for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The
+ character's individual bytes are then captured by the appropriate num-
+ ber of groups.
+
SQUARE BRACKETS AND CHARACTER CLASSES
@@ -4019,109 +4750,109 @@
closing square bracket. A closing square bracket on its own is not spe-
cial by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set,
a lone closing square bracket causes a compile-time error. If a closing
- square bracket is required as a member of the class, it should be the
- first data character in the class (after an initial circumflex, if
+ square bracket is required as a member of the class, it should be the
+ first data character in the class (after an initial circumflex, if
present) or escaped with a backslash.
- A character class matches a single character in the subject. In UTF-8
- mode, the character may be more than one byte long. A matched character
- must be in the set of characters defined by the class, unless the first
- character in the class definition is a circumflex, in which case the
- subject character must not be in the set defined by the class. If a
- circumflex is actually required as a member of the class, ensure it is
- not the first character, or escape it with a backslash.
+ A character class matches a single character in the subject. In a UTF
+ mode, the character may be more than one data unit long. A matched
+ character must be in the set of characters defined by the class, unless
+ the first character in the class definition is a circumflex, in which
+ case the subject character must not be in the set defined by the class.
+ If a circumflex is actually required as a member of the class, ensure
+ it is not the first character, or escape it with a backslash.
- For example, the character class [aeiou] matches any lower case vowel,
- while [^aeiou] matches any character that is not a lower case vowel.
+ For example, the character class [aeiou] matches any lower case vowel,
+ while [^aeiou] matches any character that is not a lower case vowel.
Note that a circumflex is just a convenient notation for specifying the
- characters that are in the class by enumerating those that are not. A
- class that starts with a circumflex is not an assertion; it still con-
- sumes a character from the subject string, and therefore it fails if
+ characters that are in the class by enumerating those that are not. A
+ class that starts with a circumflex is not an assertion; it still con-
+ sumes a character from the subject string, and therefore it fails if
the current pointer is at the end of the string.
- In UTF-8 mode, characters with values greater than 255 can be included
- in a class as a literal string of bytes, or by using the \x{ escaping
- mechanism.
-
- When caseless matching is set, any letters in a class represent both
- their upper case and lower case versions, so for example, a caseless
- [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not
- match "A", whereas a caseful version would. In UTF-8 mode, PCRE always
- understands the concept of case for characters whose values are less
- than 128, so caseless matching is always possible. For characters with
- higher values, the concept of case is supported if PCRE is compiled
- with Unicode property support, but not otherwise. If you want to use
- caseless matching in UTF8-mode for characters 128 and above, you must
- ensure that PCRE is compiled with Unicode property support as well as
- with UTF-8 support.
-
- Characters that might indicate line breaks are never treated in any
- special way when matching character classes, whatever line-ending
- sequence is in use, and whatever setting of the PCRE_DOTALL and
+ In UTF-8 (UTF-16) mode, characters with values greater than 255
+ (0xffff) can be included in a class as a literal string of data units,
+ or by using the \x{ escaping mechanism.
+
+ When caseless matching is set, any letters in a class represent both
+ their upper case and lower case versions, so for example, a caseless
+ [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not
+ match "A", whereas a caseful version would. In a UTF mode, PCRE always
+ understands the concept of case for characters whose values are less
+ than 128, so caseless matching is always possible. For characters with
+ higher values, the concept of case is supported if PCRE is compiled
+ with Unicode property support, but not otherwise. If you want to use
+ caseless matching in a UTF mode for characters 128 and above, you must
+ ensure that PCRE is compiled with Unicode property support as well as
+ with UTF support.
+
+ Characters that might indicate line breaks are never treated in any
+ special way when matching character classes, whatever line-ending
+ sequence is in use, and whatever setting of the PCRE_DOTALL and
PCRE_MULTILINE options is used. A class such as [^a] always matches one
of these characters.
- The minus (hyphen) character can be used to specify a range of charac-
- ters in a character class. For example, [d-m] matches any letter
- between d and m, inclusive. If a minus character is required in a
- class, it must be escaped with a backslash or appear in a position
- where it cannot be interpreted as indicating a range, typically as the
+ The minus (hyphen) character can be used to specify a range of charac-
+ ters in a character class. For example, [d-m] matches any letter
+ between d and m, inclusive. If a minus character is required in a
+ class, it must be escaped with a backslash or appear in a position
+ where it cannot be interpreted as indicating a range, typically as the
first or last character in the class.
It is not possible to have the literal character "]" as the end charac-
- ter of a range. A pattern such as [W-]46] is interpreted as a class of
- two characters ("W" and "-") followed by a literal string "46]", so it
- would match "W46]" or "-46]". However, if the "]" is escaped with a
- backslash it is interpreted as the end of range, so [W-\]46] is inter-
- preted as a class containing a range followed by two other characters.
- The octal or hexadecimal representation of "]" can also be used to end
+ ter of a range. A pattern such as [W-]46] is interpreted as a class of
+ two characters ("W" and "-") followed by a literal string "46]", so it
+ would match "W46]" or "-46]". However, if the "]" is escaped with a
+ backslash it is interpreted as the end of range, so [W-\]46] is inter-
+ preted as a class containing a range followed by two other characters.
+ The octal or hexadecimal representation of "]" can also be used to end
a range.
- Ranges operate in the collating sequence of character values. They can
- also be used for characters specified numerically, for example
- [\000-\037]. In UTF-8 mode, ranges can include characters whose values
- are greater than 255, for example [\x{100}-\x{2ff}].
+ Ranges operate in the collating sequence of character values. They can
+ also be used for characters specified numerically, for example
+ [\000-\037]. Ranges can include any characters that are valid for the
+ current mode.
If a range that includes letters is used when caseless matching is set,
it matches the letters in either case. For example, [W-c] is equivalent
- to [][\\^_`wxyzabc], matched caselessly, and in non-UTF-8 mode, if
- character tables for a French locale are in use, [\xc8-\xcb] matches
- accented E characters in both cases. In UTF-8 mode, PCRE supports the
- concept of case for characters with values greater than 128 only when
+ to [][\\^_`wxyzabc], matched caselessly, and in a non-UTF mode, if
+ character tables for a French locale are in use, [\xc8-\xcb] matches
+ accented E characters in both cases. In UTF modes, PCRE supports the
+ concept of case for characters with values greater than 128 only when
it is compiled with Unicode property support.
- The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V,
+ The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V,
\w, and \W may appear in a character class, and add the characters that
- they match to the class. For example, [\dABCDEF] matches any hexadeci-
- mal digit. In UTF-8 mode, the PCRE_UCP option affects the meanings of
- \d, \s, \w and their upper case partners, just as it does when they
- appear outside a character class, as described in the section entitled
+ they match to the class. For example, [\dABCDEF] matches any hexadeci-
+ mal digit. In UTF modes, the PCRE_UCP option affects the meanings of
+ \d, \s, \w and their upper case partners, just as it does when they
+ appear outside a character class, as described in the section entitled
"Generic character types" above. The escape sequence \b has a different
- meaning inside a character class; it matches the backspace character.
- The sequences \B, \N, \R, and \X are not special inside a character
- class. Like any other unrecognized escape sequences, they are treated
- as the literal characters "B", "N", "R", and "X" by default, but cause
+ meaning inside a character class; it matches the backspace character.
+ The sequences \B, \N, \R, and \X are not special inside a character
+ class. Like any other unrecognized escape sequences, they are treated
+ as the literal characters "B", "N", "R", and "X" by default, but cause
an error if the PCRE_EXTRA option is set.
- A circumflex can conveniently be used with the upper case character
- types to specify a more restricted set of characters than the matching
- lower case type. For example, the class [^\W_] matches any letter or
+ A circumflex can conveniently be used with the upper case character
+ types to specify a more restricted set of characters than the matching
+ lower case type. For example, the class [^\W_] matches any letter or
digit, but not underscore, whereas [\w] includes underscore. A positive
character class should be read as "something OR something OR ..." and a
negative class as "NOT something AND NOT something AND NOT ...".
- The only metacharacters that are recognized in character classes are
- backslash, hyphen (only where it can be interpreted as specifying a
- range), circumflex (only at the start), opening square bracket (only
- when it can be interpreted as introducing a POSIX class name - see the
- next section), and the terminating closing square bracket. However,
+ The only metacharacters that are recognized in character classes are
+ backslash, hyphen (only where it can be interpreted as specifying a
+ range), circumflex (only at the start), opening square bracket (only
+ when it can be interpreted as introducing a POSIX class name - see the
+ next section), and the terminating closing square bracket. However,
escaping other non-alphanumeric characters does no harm.
POSIX CHARACTER CLASSES
Perl supports the POSIX notation for character classes. This uses names
- enclosed by [: and :] within the enclosing square brackets. PCRE also
+ enclosed by [: and :] within the enclosing square brackets. PCRE also
supports this notation. For example,
[01[:alpha:]%]
@@ -4144,24 +4875,24 @@
word "word" characters (same as \w)
xdigit hexadecimal digits
- The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13),
- and space (32). Notice that this list includes the VT character (code
+ The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13),
+ and space (32). Notice that this list includes the VT character (code
11). This makes "space" different to \s, which does not include VT (for
Perl compatibility).
- The name "word" is a Perl extension, and "blank" is a GNU extension
- from Perl 5.8. Another Perl extension is negation, which is indicated
+ The name "word" is a Perl extension, and "blank" is a GNU extension
+ from Perl 5.8. Another Perl extension is negation, which is indicated
by a ^ character after the colon. For example,
[12[:^digit:]]
- matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the
+ matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the
POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but
these are not supported, and an error is given if they are encountered.
- By default, in UTF-8 mode, characters with values greater than 128 do
- not match any of the POSIX character classes. However, if the PCRE_UCP
- option is passed to pcre_compile(), some of the classes are changed so
+ By default, in UTF modes, characters with values greater than 128 do
+ not match any of the POSIX character classes. However, if the PCRE_UCP
+ option is passed to pcre_compile(), some of the classes are changed so
that Unicode character properties are used. This is achieved by replac-
ing the POSIX classes by other sequences, as follows:
@@ -4174,31 +4905,31 @@
[:upper:] becomes \p{Lu}
[:word:] becomes \p{Xwd}
- Negated versions, such as [:^alpha:] use \P instead of \p. The other
+ Negated versions, such as [:^alpha:] use \P instead of \p. The other
POSIX classes are unchanged, and match only characters with code points
less than 128.
VERTICAL BAR
- Vertical bar characters are used to separate alternative patterns. For
+ Vertical bar characters are used to separate alternative patterns. For
example, the pattern
gilbert|sullivan
- matches either "gilbert" or "sullivan". Any number of alternatives may
- appear, and an empty alternative is permitted (matching the empty
+ matches either "gilbert" or "sullivan". Any number of alternatives may
+ appear, and an empty alternative is permitted (matching the empty
string). The matching process tries each alternative in turn, from left
- to right, and the first one that succeeds is used. If the alternatives
- are within a subpattern (defined below), "succeeds" means matching the
+ to right, and the first one that succeeds is used. If the alternatives
+ are within a subpattern (defined below), "succeeds" means matching the
rest of the main pattern as well as the alternative in the subpattern.
INTERNAL OPTION SETTING
- The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and
- PCRE_EXTENDED options (which are Perl-compatible) can be changed from
- within the pattern by a sequence of Perl option letters enclosed
+ The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and
+ PCRE_EXTENDED options (which are Perl-compatible) can be changed from
+ within the pattern by a sequence of Perl option letters enclosed
between "(?" and ")". The option letters are
i for PCRE_CASELESS
@@ -4208,48 +4939,49 @@
For example, (?im) sets caseless, multiline matching. It is also possi-
ble to unset these options by preceding the letter with a hyphen, and a
- combined setting and unsetting such as (?im-sx), which sets PCRE_CASE-
- LESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED,
- is also permitted. If a letter appears both before and after the
+ combined setting and unsetting such as (?im-sx), which sets PCRE_CASE-
+ LESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED,
+ is also permitted. If a letter appears both before and after the
hyphen, the option is unset.
- The PCRE-specific options PCRE_DUPNAMES, PCRE_UNGREEDY, and PCRE_EXTRA
- can be changed in the same way as the Perl-compatible options by using
+ The PCRE-specific options PCRE_DUPNAMES, PCRE_UNGREEDY, and PCRE_EXTRA
+ can be changed in the same way as the Perl-compatible options by using
the characters J, U and X respectively.
- When one of these option changes occurs at top level (that is, not
- inside subpattern parentheses), the change applies to the remainder of
+ When one of these option changes occurs at top level (that is, not
+ inside subpattern parentheses), the change applies to the remainder of
the pattern that follows. If the change is placed right at the start of
a pattern, PCRE extracts it into the global options (and it will there-
fore show up in data extracted by the pcre_fullinfo() function).
- An option change within a subpattern (see below for a description of
- subpatterns) affects only that part of the subpattern that follows it,
+ An option change within a subpattern (see below for a description of
+ subpatterns) affects only that part of the subpattern that follows it,
so
(a(?i)b)c
matches abc and aBc and no other strings (assuming PCRE_CASELESS is not
- used). By this means, options can be made to have different settings
- in different parts of the pattern. Any changes made in one alternative
- do carry on into subsequent branches within the same subpattern. For
+ used). By this means, options can be made to have different settings
+ in different parts of the pattern. Any changes made in one alternative
+ do carry on into subsequent branches within the same subpattern. For
example,
(a(?i)b|c)
- matches "ab", "aB", "c", and "C", even though when matching "C" the
- first branch is abandoned before the option setting. This is because
- the effects of option settings happen at compile time. There would be
+ matches "ab", "aB", "c", and "C", even though when matching "C" the
+ first branch is abandoned before the option setting. This is because
+ the effects of option settings happen at compile time. There would be
some very weird behaviour otherwise.
- Note: There are other PCRE-specific options that can be set by the
- application when the compile or match functions are called. In some
- cases the pattern can contain special leading sequences such as (*CRLF)
- to override what the application has set or what has been defaulted.
- Details are given in the section entitled "Newline sequences" above.
- There are also the (*UTF8) and (*UCP) leading sequences that can be
- used to set UTF-8 and Unicode property modes; they are equivalent to
- setting the PCRE_UTF8 and the PCRE_UCP options, respectively.
+ Note: There are other PCRE-specific options that can be set by the
+ application when the compiling or matching functions are called. In
+ some cases the pattern can contain special leading sequences such as
+ (*CRLF) to override what the application has set or what has been
+ defaulted. Details are given in the section entitled "Newline
+ sequences" above. There are also the (*UTF8), (*UTF16), and (*UCP)
+ leading sequences that can be used to set UTF and Unicode property
+ modes; they are equivalent to setting the PCRE_UTF8, PCRE_UTF16, and
+ the PCRE_UCP options, respectively.
SUBPATTERNS
@@ -4267,22 +4999,25 @@
2. It sets up the subpattern as a capturing subpattern. This means
that, when the whole pattern matches, that portion of the subject
string that matched the subpattern is passed back to the caller via the
- ovector argument of pcre_exec(). Opening parentheses are counted from
- left to right (starting from 1) to obtain numbers for the capturing
- subpatterns. For example, if the string "the red king" is matched
- against the pattern
+ ovector argument of the matching function. (This applies only to the
+ traditional matching functions; the DFA matching functions do not sup-
+ port capturing.)
+
+ Opening parentheses are counted from left to right (starting from 1) to
+ obtain numbers for the capturing subpatterns. For example, if the
+ string "the red king" is matched against the pattern
the ((red|white) (king|queen))
the captured substrings are "red king", "red", and "king", and are num-
bered 1, 2, and 3, respectively.
- The fact that plain parentheses fulfil two functions is not always
- helpful. There are often times when a grouping subpattern is required
- without a capturing requirement. If an opening parenthesis is followed
- by a question mark and a colon, the subpattern does not do any captur-
- ing, and is not counted when computing the number of any subsequent
- capturing subpatterns. For example, if the string "the white queen" is
+ The fact that plain parentheses fulfil two functions is not always
+ helpful. There are often times when a grouping subpattern is required
+ without a capturing requirement. If an opening parenthesis is followed
+ by a question mark and a colon, the subpattern does not do any captur-
+ ing, and is not counted when computing the number of any subsequent
+ capturing subpatterns. For example, if the string "the white queen" is
matched against the pattern
the ((?:red|white) (king|queen))
@@ -4290,37 +5025,37 @@
the captured substrings are "white queen" and "queen", and are numbered
1 and 2. The maximum number of capturing subpatterns is 65535.
- As a convenient shorthand, if any option settings are required at the
- start of a non-capturing subpattern, the option letters may appear
+ As a convenient shorthand, if any option settings are required at the
+ start of a non-capturing subpattern, the option letters may appear
between the "?" and the ":". Thus the two patterns
(?i:saturday|sunday)
(?:(?i)saturday|sunday)
match exactly the same set of strings. Because alternative branches are
- tried from left to right, and options are not reset until the end of
- the subpattern is reached, an option setting in one branch does affect
- subsequent branches, so the above patterns match "SUNDAY" as well as
+ tried from left to right, and options are not reset until the end of
+ the subpattern is reached, an option setting in one branch does affect
+ subsequent branches, so the above patterns match "SUNDAY" as well as
"Saturday".
DUPLICATE SUBPATTERN NUMBERS
Perl 5.10 introduced a feature whereby each alternative in a subpattern
- uses the same numbers for its capturing parentheses. Such a subpattern
- starts with (?| and is itself a non-capturing subpattern. For example,
+ uses the same numbers for its capturing parentheses. Such a subpattern
+ starts with (?| and is itself a non-capturing subpattern. For example,
consider this pattern:
(?|(Sat)ur|(Sun))day
- Because the two alternatives are inside a (?| group, both sets of cap-
- turing parentheses are numbered one. Thus, when the pattern matches,
- you can look at captured substring number one, whichever alternative
- matched. This construct is useful when you want to capture part, but
+ Because the two alternatives are inside a (?| group, both sets of cap-
+ turing parentheses are numbered one. Thus, when the pattern matches,
+ you can look at captured substring number one, whichever alternative
+ matched. This construct is useful when you want to capture part, but
not all, of one of a number of alternatives. Inside a (?| group, paren-
- theses are numbered as usual, but the number is reset at the start of
- each branch. The numbers of any capturing parentheses that follow the
- subpattern start after the highest number used in any branch. The fol-
+ theses are numbered as usual, but the number is reset at the start of
+ each branch. The numbers of any capturing parentheses that follow the
+ subpattern start after the highest number used in any branch. The fol-
lowing example is taken from the Perl documentation. The numbers under-
neath show in which buffer the captured content will be stored.
@@ -4328,58 +5063,58 @@
/ ( a ) (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x
# 1 2 2 3 2 3 4
- A back reference to a numbered subpattern uses the most recent value
- that is set for that number by any subpattern. The following pattern
+ A back reference to a numbered subpattern uses the most recent value
+ that is set for that number by any subpattern. The following pattern
matches "abcabc" or "defdef":
/(?|(abc)|(def))\1/
- In contrast, a recursive or "subroutine" call to a numbered subpattern
- always refers to the first one in the pattern with the given number.
- The following pattern matches "abcabc" or "defabc":
+ In contrast, a subroutine call to a numbered subpattern always refers
+ to the first one in the pattern with the given number. The following
+ pattern matches "abcabc" or "defabc":
/(?|(abc)|(def))(?1)/
- If a condition test for a subpattern's having matched refers to a non-
- unique number, the test is true if any of the subpatterns of that num-
+ If a condition test for a subpattern's having matched refers to a non-
+ unique number, the test is true if any of the subpatterns of that num-
ber have matched.
- An alternative approach to using this "branch reset" feature is to use
+ An alternative approach to using this "branch reset" feature is to use
duplicate named subpatterns, as described in the next section.
NAMED SUBPATTERNS
- Identifying capturing parentheses by number is simple, but it can be
- very hard to keep track of the numbers in complicated regular expres-
- sions. Furthermore, if an expression is modified, the numbers may
- change. To help with this difficulty, PCRE supports the naming of sub-
+ Identifying capturing parentheses by number is simple, but it can be
+ very hard to keep track of the numbers in complicated regular expres-
+ sions. Furthermore, if an expression is modified, the numbers may
+ change. To help with this difficulty, PCRE supports the naming of sub-
patterns. This feature was not added to Perl until release 5.10. Python
- had the feature earlier, and PCRE introduced it at release 4.0, using
- the Python syntax. PCRE now supports both the Perl and the Python syn-
- tax. Perl allows identically numbered subpatterns to have different
+ had the feature earlier, and PCRE introduced it at release 4.0, using
+ the Python syntax. PCRE now supports both the Perl and the Python syn-
+ tax. Perl allows identically numbered subpatterns to have different
names, but PCRE does not.
- In PCRE, a subpattern can be named in one of three ways: (?...)
- or (?'name'...) as in Perl, or (?P...) as in Python. References
- to capturing parentheses from other parts of the pattern, such as back
- references, recursion, and conditions, can be made by name as well as
+ In PCRE, a subpattern can be named in one of three ways: (?...)
+ or (?'name'...) as in Perl, or (?P...) as in Python. References
+ to capturing parentheses from other parts of the pattern, such as back
+ references, recursion, and conditions, can be made by name as well as
by number.
- Names consist of up to 32 alphanumeric characters and underscores.
- Named capturing parentheses are still allocated numbers as well as
- names, exactly as if the names were not present. The PCRE API provides
+ Names consist of up to 32 alphanumeric characters and underscores.
+ Named capturing parentheses are still allocated numbers as well as
+ names, exactly as if the names were not present. The PCRE API provides
function calls for extracting the name-to-number translation table from
a compiled pattern. There is also a convenience function for extracting
a captured substring by name.
- By default, a name must be unique within a pattern, but it is possible
+ By default, a name must be unique within a pattern, but it is possible
to relax this constraint by setting the PCRE_DUPNAMES option at compile
- time. (Duplicate names are also always permitted for subpatterns with
- the same number, set up as described in the previous section.) Dupli-
- cate names can be useful for patterns where only one instance of the
- named parentheses can match. Suppose you want to match the name of a
- weekday, either as a 3-letter abbreviation or as the full name, and in
+ time. (Duplicate names are also always permitted for subpatterns with
+ the same number, set up as described in the previous section.) Dupli-
+ cate names can be useful for patterns where only one instance of the
+ named parentheses can match. Suppose you want to match the name of a
+ weekday, either as a 3-letter abbreviation or as the full name, and in
both cases you want to extract the abbreviation. This pattern (ignoring
the line breaks) does the job:
@@ -4389,62 +5124,62 @@
(?Thu)(?:rsday)?|
(?Sat)(?:urday)?
- There are five capturing substrings, but only one is ever set after a
+ There are five capturing substrings, but only one is ever set after a
match. (An alternative way of solving this problem is to use a "branch
reset" subpattern, as described in the previous section.)
- The convenience function for extracting the data by name returns the
- substring for the first (and in this example, the only) subpattern of
- that name that matched. This saves searching to find which numbered
+ The convenience function for extracting the data by name returns the
+ substring for the first (and in this example, the only) subpattern of
+ that name that matched. This saves searching to find which numbered
subpattern it was.
- If you make a back reference to a non-unique named subpattern from
- elsewhere in the pattern, the one that corresponds to the first occur-
+ If you make a back reference to a non-unique named subpattern from
+ elsewhere in the pattern, the one that corresponds to the first occur-
rence of the name is used. In the absence of duplicate numbers (see the
- previous section) this is the one with the lowest number. If you use a
- named reference in a condition test (see the section about conditions
- below), either to check whether a subpattern has matched, or to check
- for recursion, all subpatterns with the same name are tested. If the
- condition is true for any one of them, the overall condition is true.
+ previous section) this is the one with the lowest number. If you use a
+ named reference in a condition test (see the section about conditions
+ below), either to check whether a subpattern has matched, or to check
+ for recursion, all subpatterns with the same name are tested. If the
+ condition is true for any one of them, the overall condition is true.
This is the same behaviour as testing by number. For further details of
the interfaces for handling named subpatterns, see the pcreapi documen-
tation.
Warning: You cannot use different names to distinguish between two sub-
- patterns with the same number because PCRE uses only the numbers when
+ patterns with the same number because PCRE uses only the numbers when
matching. For this reason, an error is given at compile time if differ-
- ent names are given to subpatterns with the same number. However, you
- can give the same name to subpatterns with the same number, even when
+ ent names are given to subpatterns with the same number. However, you
+ can give the same name to subpatterns with the same number, even when
PCRE_DUPNAMES is not set.
REPETITION
- Repetition is specified by quantifiers, which can follow any of the
+ Repetition is specified by quantifiers, which can follow any of the
following items:
a literal data character
the dot metacharacter
the \C escape sequence
- the \X escape sequence (in UTF-8 mode with Unicode properties)
+ the \X escape sequence
the \R escape sequence
an escape such as \d or \pL that matches a single character
a character class
a back reference (see next section)
- a parenthesized subpattern (unless it is an assertion)
- a recursive or "subroutine" call to a subpattern
+ a parenthesized subpattern (including assertions)
+ a subroutine call to a subpattern (recursive or otherwise)
- The general repetition quantifier specifies a minimum and maximum num-
- ber of permitted matches, by giving the two numbers in curly brackets
- (braces), separated by a comma. The numbers must be less than 65536,
+ The general repetition quantifier specifies a minimum and maximum num-
+ ber of permitted matches, by giving the two numbers in curly brackets
+ (braces), separated by a comma. The numbers must be less than 65536,
and the first must be less than or equal to the second. For example:
z{2,4}
- matches "zz", "zzz", or "zzzz". A closing brace on its own is not a
- special character. If the second number is omitted, but the comma is
- present, there is no upper limit; if the second number and the comma
- are both omitted, the quantifier specifies an exact number of required
+ matches "zz", "zzz", or "zzzz". A closing brace on its own is not a
+ special character. If the second number is omitted, but the comma is
+ present, there is no upper limit; if the second number and the comma
+ are both omitted, the quantifier specifies an exact number of required
matches. Thus
[aeiou]{3,}
@@ -4453,17 +5188,16 @@
\d{8}
- matches exactly 8 digits. An opening curly bracket that appears in a
- position where a quantifier is not allowed, or one that does not match
- the syntax of a quantifier, is taken as a literal character. For exam-
+ matches exactly 8 digits. An opening curly bracket that appears in a
+ position where a quantifier is not allowed, or one that does not match
+ the syntax of a quantifier, is taken as a literal character. For exam-
ple, {,6} is not a quantifier, but a literal string of four characters.
- In UTF-8 mode, quantifiers apply to UTF-8 characters rather than to
- individual bytes. Thus, for example, \x{100}{2} matches two UTF-8 char-
- acters, each of which is represented by a two-byte sequence. Similarly,
- when Unicode property support is available, \X{3} matches three Unicode
- extended sequences, each of which may be several bytes long (and they
- may be of different lengths).
+ In UTF modes, quantifiers apply to characters rather than to individual
+ data units. Thus, for example, \x{100}{2} matches two characters, each
+ of which is represented by a two-byte sequence in a UTF-8 string. Simi-
+ larly, \X{3} matches three Unicode extended sequences, each of which
+ may be several data units long (and they may be of different lengths).
The quantifier {0} is permitted, causing the expression to behave as if
the previous item and the quantifier were not present. This may be use-
@@ -4769,8 +5503,8 @@
its following a backslash are taken as part of a potential back refer-
ence number. If the pattern continues with a digit character, some
delimiter must be used to terminate the back reference. If the
- PCRE_EXTENDED option is set, this can be whitespace. Otherwise, the \g{
- syntax or an empty comment (see "Comments" below) can be used.
+ PCRE_EXTENDED option is set, this can be white space. Otherwise, the
+ \g{ syntax or an empty comment (see "Comments" below) can be used.
Recursive back references
@@ -4807,13 +5541,29 @@
matched in the normal way, except that it does not cause the current
matching position to be changed.
- Assertion subpatterns are not capturing subpatterns, and may not be
- repeated, because it makes no sense to assert the same thing several
- times. If any kind of assertion contains capturing subpatterns within
- it, these are counted for the purposes of numbering the capturing sub-
- patterns in the whole pattern. However, substring capturing is carried
- out only for positive assertions, because it does not make sense for
- negative assertions.
+ Assertion subpatterns are not capturing subpatterns. If such an asser-
+ tion contains capturing subpatterns within it, these are counted for
+ the purposes of numbering the capturing subpatterns in the whole pat-
+ tern. However, substring capturing is carried out only for positive
+ assertions, because it does not make sense for negative assertions.
+
+ For compatibility with Perl, assertion subpatterns may be repeated;
+ though it makes no sense to assert the same thing several times, the
+ side effect of capturing parentheses may occasionally be useful. In
+ practice, there only three cases:
+
+ (1) If the quantifier is {0}, the assertion is never obeyed during
+ matching. However, it may contain internal capturing parenthesized
+ groups that are called from elsewhere via the subroutine mechanism.
+
+ (2) If quantifier is {0,n} where n is greater than zero, it is treated
+ as if it were {0,1}. At run time, the rest of the pattern match is
+ tried with and without the assertion, the order depending on the greed-
+ iness of the quantifier.
+
+ (3) If the minimum repetition is greater than zero, the quantifier is
+ ignored. The assertion is obeyed just once when encountered during
+ matching.
Lookahead assertions
@@ -4883,40 +5633,41 @@
then try to match. If there are insufficient characters before the cur-
rent position, the assertion fails.
- PCRE does not allow the \C escape (which matches a single byte in UTF-8
- mode) to appear in lookbehind assertions, because it makes it impossi-
- ble to calculate the length of the lookbehind. The \X and \R escapes,
- which can match different numbers of bytes, are also not permitted.
+ In a UTF mode, PCRE does not allow the \C escape (which matches a sin-
+ gle data unit even in a UTF mode) to appear in lookbehind assertions,
+ because it makes it impossible to calculate the length of the lookbe-
+ hind. The \X and \R escapes, which can match different numbers of data
+ units, are also not permitted.
- "Subroutine" calls (see below) such as (?2) or (?&X) are permitted in
- lookbehinds, as long as the subpattern matches a fixed-length string.
+ "Subroutine" calls (see below) such as (?2) or (?&X) are permitted in
+ lookbehinds, as long as the subpattern matches a fixed-length string.
Recursion, however, is not supported.
- Possessive quantifiers can be used in conjunction with lookbehind
+ Possessive quantifiers can be used in conjunction with lookbehind
assertions to specify efficient matching of fixed-length strings at the
end of subject strings. Consider a simple pattern such as
abcd$
- when applied to a long string that does not match. Because matching
+ when applied to a long string that does not match. Because matching
proceeds from left to right, PCRE will look for each "a" in the subject
- and then see if what follows matches the rest of the pattern. If the
+ and then see if what follows matches the rest of the pattern. If the
pattern is specified as
^.*abcd$
- the initial .* matches the entire string at first, but when this fails
+ the initial .* matches the entire string at first, but when this fails
(because there is no following "a"), it backtracks to match all but the
- last character, then all but the last two characters, and so on. Once
- again the search for "a" covers the entire string, from right to left,
+ last character, then all but the last two characters, and so on. Once
+ again the search for "a" covers the entire string, from right to left,
so we are no better off. However, if the pattern is written as
^.*+(?<=abcd)
- there can be no backtracking for the .*+ item; it can match only the
- entire string. The subsequent lookbehind assertion does a single test
- on the last four characters. If it fails, the match fails immediately.
- For long strings, this approach makes a significant difference to the
+ there can be no backtracking for the .*+ item; it can match only the
+ entire string. The subsequent lookbehind assertion does a single test
+ on the last four characters. If it fails, the match fails immediately.
+ For long strings, this approach makes a significant difference to the
processing time.
Using multiple assertions
@@ -4925,18 +5676,18 @@
(?<=\d{3})(?)...) or (?('name')...) to test for a
- used subpattern by name. For compatibility with earlier versions of
- PCRE, which had this facility before Perl, the syntax (?(name)...) is
- also recognized. However, there is a possible ambiguity with this syn-
- tax, because subpattern names may consist entirely of digits. PCRE
- looks first for a named subpattern; if it cannot find one and the name
- consists entirely of digits, PCRE looks for a subpattern of that num-
- ber, which must be greater than zero. Using subpattern names that con-
+ Perl uses the syntax (?()...) or (?('name')...) to test for a
+ used subpattern by name. For compatibility with earlier versions of
+ PCRE, which had this facility before Perl, the syntax (?(name)...) is
+ also recognized. However, there is a possible ambiguity with this syn-
+ tax, because subpattern names may consist entirely of digits. PCRE
+ looks first for a named subpattern; if it cannot find one and the name
+ consists entirely of digits, PCRE looks for a subpattern of that num-
+ ber, which must be greater than zero. Using subpattern names that con-
sist entirely of digits is not recommended.
Rewriting the above example to use a named subpattern gives this:
(? \( )? [^()]+ (?() \) )
- If the name used in a condition of this kind is a duplicate, the test
- is applied to all subpatterns of the same name, and is true if any one
+ If the name used in a condition of this kind is a duplicate, the test
+ is applied to all subpatterns of the same name, and is true if any one
of them has matched.
Checking for pattern recursion
If the condition is the string (R), and there is no subpattern with the
- name R, the condition is true if a recursive call to the whole pattern
+ name R, the condition is true if a recursive call to the whole pattern
or any subpattern has been made. If digits or a name preceded by amper-
sand follow the letter R, for example:
@@ -5049,24 +5800,23 @@
the condition is true if the most recent recursion is into a subpattern
whose number or name is given. This condition does not check the entire
- recursion stack. If the name used in a condition of this kind is a
+ recursion stack. If the name used in a condition of this kind is a
duplicate, the test is applied to all subpatterns of the same name, and
is true if any one of them is the most recent recursion.
- At "top level", all these recursion test conditions are false. The
+ At "top level", all these recursion test conditions are false. The
syntax for recursive patterns is described below.
Defining subpatterns for use by reference only
- If the condition is the string (DEFINE), and there is no subpattern
- with the name DEFINE, the condition is always false. In this case,
- there may be only one alternative in the subpattern. It is always
- skipped if control reaches this point in the pattern; the idea of
- DEFINE is that it can be used to define "subroutines" that can be ref-
- erenced from elsewhere. (The use of "subroutines" is described below.)
- For example, a pattern to match an IPv4 address such as
- "192.168.23.245" could be written like this (ignore whitespace and line
- breaks):
+ If the condition is the string (DEFINE), and there is no subpattern
+ with the name DEFINE, the condition is always false. In this case,
+ there may be only one alternative in the subpattern. It is always
+ skipped if control reaches this point in the pattern; the idea of
+ DEFINE is that it can be used to define subroutines that can be refer-
+ enced from elsewhere. (The use of subroutines is described below.) For
+ example, a pattern to match an IPv4 address such as "192.168.23.245"
+ could be written like this (ignore white space and line breaks):
(?(DEFINE) (? 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
\b (?&byte) (\.(?&byte)){3} \b
@@ -5112,12 +5862,12 @@
comment, which in this case continues to immediately after the next
newline character or character sequence in the pattern. Which charac-
ters are interpreted as newlines is controlled by the options passed to
- pcre_compile() or by a special sequence at the start of the pattern, as
- described in the section entitled "Newline conventions" above. Note
- that the end of this type of comment is a literal newline sequence in
- the pattern; escape sequences that happen to represent a newline do not
- count. For example, consider this pattern when PCRE_EXTENDED is set,
- and the default newline convention is in force:
+ a compiling function or by a special sequence at the start of the pat-
+ tern, as described in the section entitled "Newline conventions" above.
+ Note that the end of this type of comment is a literal newline sequence
+ in the pattern; escape sequences that happen to represent a newline do
+ not count. For example, consider this pattern when PCRE_EXTENDED is
+ set, and the default newline convention is in force:
abc #comment \n still comment
@@ -5153,11 +5903,11 @@
into Perl at release 5.10.
A special item that consists of (? followed by a number greater than
- zero and a closing parenthesis is a recursive call of the subpattern of
- the given number, provided that it occurs inside that subpattern. (If
- not, it is a "subroutine" call, which is described in the next sec-
- tion.) The special item (?R) or (?0) is a recursive call of the entire
- regular expression.
+ zero and a closing parenthesis is a recursive subroutine call of the
+ subpattern of the given number, provided that it occurs inside that
+ subpattern. (If not, it is a non-recursive subroutine call, which is
+ described in the next section.) The special item (?R) or (?0) is a
+ recursive call of the entire regular expression.
This PCRE pattern solves the nested parentheses problem (assume the
PCRE_EXTENDED option is set so that white space is ignored):
@@ -5189,8 +5939,8 @@
It is also possible to refer to subsequently opened parentheses, by
writing references such as (?+2). However, these cannot be recursive
because the reference is not inside the parentheses that are refer-
- enced. They are always "subroutine" calls, as described in the next
- section.
+ enced. They are always non-recursive subroutine calls, as described in
+ the next section.
An alternative approach is to use named parentheses instead. The Perl
syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also
@@ -5223,28 +5973,30 @@
the value for the inner capturing parentheses (numbered 2) is "ef",
which is the last value taken on at the top level. If a capturing sub-
- pattern is not matched at the top level, its final value is unset, even
- if it is (temporarily) set at a deeper level.
+ pattern is not matched at the top level, its final captured value is
+ unset, even if it was (temporarily) set at a deeper level during the
+ matching process.
- If there are more than 15 capturing parentheses in a pattern, PCRE has
- to obtain extra memory to store data during a recursion, which it does
+ If there are more than 15 capturing parentheses in a pattern, PCRE has
+ to obtain extra memory to store data during a recursion, which it does
by using pcre_malloc, freeing it via pcre_free afterwards. If no memory
can be obtained, the match fails with the PCRE_ERROR_NOMEMORY error.
- Do not confuse the (?R) item with the condition (R), which tests for
- recursion. Consider this pattern, which matches text in angle brack-
- ets, allowing for arbitrary nesting. Only digits are allowed in nested
- brackets (that is, when recursing), whereas any characters are permit-
+ Do not confuse the (?R) item with the condition (R), which tests for
+ recursion. Consider this pattern, which matches text in angle brack-
+ ets, allowing for arbitrary nesting. Only digits are allowed in nested
+ brackets (that is, when recursing), whereas any characters are permit-
ted at the outer level.
< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >
- In this pattern, (?(R) is the start of a conditional subpattern, with
- two different alternatives for the recursive and non-recursive cases.
+ In this pattern, (?(R) is the start of a conditional subpattern, with
+ two different alternatives for the recursive and non-recursive cases.
The (?R) item is the actual recursive call.
- Recursion difference from Perl
+ Differences in recursion processing between PCRE and Perl
+ Recursion processing in PCRE differs from Perl in two important ways.
In PCRE (like Python, but unlike Perl), a recursive subpattern call is
always treated as an atomic group. That is, once it has matched some of
the subject string, it is never re-entered, even if it contains untried
@@ -5317,14 +6069,30 @@
Once again, it cannot jump back into the recursion to try other alter-
natives, so the entire match fails.
+ The second way in which PCRE and Perl differ in their recursion pro-
+ cessing is in the handling of captured values. In Perl, when a subpat-
+ tern is called recursively or as a subpattern (see the next section),
+ it has no access to any values that were captured outside the recur-
+ sion, whereas in PCRE these values can be referenced. Consider this
+ pattern:
+
+ ^(.)(\1|a(?2))
+
+ In PCRE, this pattern matches "bab". The first capturing parentheses
+ match "b", then in the second group, when the back reference \1 fails
+ to match "b", the second alternative matches "a" and then recurses. In
+ the recursion, \1 does now match "b" and so the whole match succeeds.
+ In Perl, the pattern fails to match because inside the recursive call
+ \1 cannot access the externally set value.
+
SUBPATTERNS AS SUBROUTINES
- If the syntax for a recursive subpattern reference (either by number or
- by name) is used outside the parentheses to which it refers, it oper-
- ates like a subroutine in a programming language. The "called" subpat-
- tern may be defined before or after the reference. A numbered reference
- can be absolute or relative, as in these examples:
+ If the syntax for a recursive subpattern call (either by number or by
+ name) is used outside the parentheses to which it refers, it operates
+ like a subroutine in a programming language. The called subpattern may
+ be defined before or after the reference. A numbered reference can be
+ absolute or relative, as in these examples:
(...(absolute)...)...(?2)...
(...(relative)...)...(?-1)...
@@ -5343,15 +6111,15 @@
two strings. Another example is given in the discussion of DEFINE
above.
- Like recursive subpatterns, a subroutine call is always treated as an
- atomic group. That is, once it has matched some of the subject string,
- it is never re-entered, even if it contains untried alternatives and
- there is a subsequent matching failure. Any capturing parentheses that
- are set during the subroutine call revert to their previous values
- afterwards.
+ All subroutine calls, whether recursive or not, are always treated as
+ atomic groups. That is, once a subroutine has matched some of the sub-
+ ject string, it is never re-entered, even if it contains untried alter-
+ natives and there is a subsequent matching failure. Any capturing
+ parentheses that are set during the subroutine call revert to their
+ previous values afterwards.
- When a subpattern is used as a subroutine, processing options such as
- case-independence are fixed when the subpattern is defined. They cannot
+ Processing options such as case-independence are fixed when a subpat-
+ tern is defined, so if it is used as a subroutine, such options cannot
be changed for different calls. For example, consider this pattern:
(abc)(?i:(?-1))
@@ -5392,8 +6160,8 @@
PCRE provides a similar feature, but of course it cannot obey arbitrary
Perl code. The feature is called "callout". The caller of PCRE provides
an external function by putting its entry point in the global variable
- pcre_callout. By default, this variable contains NULL, which disables
- all calling out.
+ pcre_callout (8-bit library) or pcre16_callout (16-bit library). By
+ default, this variable contains NULL, which disables all calling out.
Within a regular expression, (?C) indicates the points at which the
external function is to be called. If you want to identify different
@@ -5403,17 +6171,17 @@
(?C1)abc(?C2)def
- If the PCRE_AUTO_CALLOUT flag is passed to pcre_compile(), callouts are
- automatically installed before each item in the pattern. They are all
- numbered 255.
-
- During matching, when PCRE reaches a callout point (and pcre_callout is
- set), the external function is called. It is provided with the number
- of the callout, the position in the pattern, and, optionally, one item
- of data originally supplied by the caller of pcre_exec(). The callout
- function may cause matching to proceed, to backtrack, or to fail alto-
- gether. A complete description of the interface to the callout function
- is given in the pcrecallout documentation.
+ If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, call-
+ outs are automatically installed before each item in the pattern. They
+ are all numbered 255.
+
+ During matching, when PCRE reaches a callout point, the external func-
+ tion is called. It is provided with the number of the callout, the
+ position in the pattern, and, optionally, one item of data originally
+ supplied by the caller of the matching function. The callout function
+ may cause matching to proceed, to backtrack, or to fail altogether. A
+ complete description of the interface to the callout function is given
+ in the pcrecallout documentation.
BACKTRACKING CONTROL
@@ -5426,25 +6194,33 @@
in this section.
Since these verbs are specifically related to backtracking, most of
- them can be used only when the pattern is to be matched using
- pcre_exec(), which uses a backtracking algorithm. With the exception of
- (*FAIL), which behaves like a failing negative assertion, they cause an
- error if encountered by pcre_dfa_exec().
-
- If any of these verbs are used in an assertion or subroutine subpattern
- (including recursive subpatterns), their effect is confined to that
- subpattern; it does not extend to the surrounding pattern. Note that
- such subpatterns are processed as anchored at the point where they are
- tested.
+ them can be used only when the pattern is to be matched using one of
+ the traditional matching functions, which use a backtracking algorithm.
+ With the exception of (*FAIL), which behaves like a failing negative
+ assertion, they cause an error if encountered by a DFA matching func-
+ tion.
- The new verbs make use of what was previously invalid syntax: an open-
+ If any of these verbs are used in an assertion or in a subpattern that
+ is called as a subroutine (whether or not recursively), their effect is
+ confined to that subpattern; it does not extend to the surrounding pat-
+ tern, with one exception: the name from a *(MARK), (*PRUNE), or (*THEN)
+ that is encountered in a successful positive assertion is passed back
+ when a match succeeds (compare capturing parentheses in assertions).
+ Note that such subpatterns are processed as anchored at the point where
+ they are tested. Note also that Perl's treatment of subroutines and
+ assertions is different in some cases.
+
+ The new verbs make use of what was previously invalid syntax: an open-
ing parenthesis followed by an asterisk. They are generally of the form
- (*VERB) or (*VERB:NAME). Some may take either form, with differing be-
- haviour, depending on whether or not an argument is present. An name is
- a sequence of letters, digits, and underscores. If the name is empty,
- that is, if the closing parenthesis immediately follows the colon, the
- effect is as if the colon were not there. Any number of these verbs may
- occur in a pattern.
+ (*VERB) or (*VERB:NAME). Some may take either form, with differing be-
+ haviour, depending on whether or not an argument is present. A name is
+ any sequence of characters that does not include a closing parenthesis.
+ The maximum length of name is 255 in the 8-bit library and 65535 in the
+ 16-bit library. If the name is empty, that is, if the closing parenthe-
+ sis immediately follows the colon, the effect is as if the colon were
+ not there. Any number of these verbs may occur in a pattern.
+
+ Optimizations that affect backtracking verbs
PCRE contains some optimizations that are used to speed up matching by
running some checks at the start of each match attempt. For example, it
@@ -5454,60 +6230,64 @@
course, be processed. You can suppress the start-of-match optimizations
by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_com-
pile() or pcre_exec(), or by starting the pattern with (*NO_START_OPT).
+ There is more discussion of this option in the section entitled "Option
+ bits for pcre_exec()" in the pcreapi documentation.
+
+ Experiments with Perl suggest that it too has similar optimizations,
+ sometimes leading to anomalous results.
Verbs that act immediately
- The following verbs act as soon as they are encountered. They may not
+ The following verbs act as soon as they are encountered. They may not
be followed by a name.
(*ACCEPT)
- This verb causes the match to end successfully, skipping the remainder
- of the pattern. When inside a recursion, only the innermost pattern is
- ended immediately. If (*ACCEPT) is inside capturing parentheses, the
- data so far is captured. (This feature was added to PCRE at release
- 8.00.) For example:
+ This verb causes the match to end successfully, skipping the remainder
+ of the pattern. However, when it is inside a subpattern that is called
+ as a subroutine, only that subpattern is ended successfully. Matching
+ then continues at the outer level. If (*ACCEPT) is inside capturing
+ parentheses, the data so far is captured. For example:
A((?:A|B(*ACCEPT)|C)D)
- This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap-
+ This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap-
tured by the outer parentheses.
(*FAIL) or (*F)
- This verb causes the match to fail, forcing backtracking to occur. It
- is equivalent to (?!) but easier to read. The Perl documentation notes
- that it is probably useful only when combined with (?{}) or (??{}).
- Those are, of course, Perl features that are not present in PCRE. The
- nearest equivalent is the callout feature, as for example in this pat-
+ This verb causes a matching failure, forcing backtracking to occur. It
+ is equivalent to (?!) but easier to read. The Perl documentation notes
+ that it is probably useful only when combined with (?{}) or (??{}).
+ Those are, of course, Perl features that are not present in PCRE. The
+ nearest equivalent is the callout feature, as for example in this pat-
tern:
a+(?C)(*FAIL)
- A match with the string "aaaa" always fails, but the callout is taken
+ A match with the string "aaaa" always fails, but the callout is taken
before each backtrack happens (in this example, 10 times).
Recording which path was taken
- There is one verb whose main purpose is to track how a match was
- arrived at, though it also has a secondary use in conjunction with
+ There is one verb whose main purpose is to track how a match was
+ arrived at, though it also has a secondary use in conjunction with
advancing the match starting point (see (*SKIP) below).
(*MARK:NAME) or (*:NAME)
- A name is always required with this verb. There may be as many
- instances of (*MARK) as you like in a pattern, and their names do not
+ A name is always required with this verb. There may be as many
+ instances of (*MARK) as you like in a pattern, and their names do not
have to be unique.
- When a match succeeds, the name of the last-encountered (*MARK) is
- passed back to the caller via the pcre_extra data structure, as
- described in the section on pcre_extra in the pcreapi documentation. No
- data is returned for a partial match. Here is an example of pcretest
- output, where the /K modifier requests the retrieval and outputting of
- (*MARK) data:
+ When a match succeeds, the name of the last-encountered (*MARK) on the
+ matching path is passed back to the caller as described in the section
+ entitled "Extra data for pcre_exec()" in the pcreapi documentation.
+ Here is an example of pcretest output, where the /K modifier requests
+ the retrieval and outputting of (*MARK) data:
- /X(*MARK:A)Y|X(*MARK:B)Z/K
- XY
+ re> /X(*MARK:A)Y|X(*MARK:B)Z/K
+ data> XY
0: XY
MK: A
XZ
@@ -5519,98 +6299,86 @@
efficient way of obtaining this information than putting each alterna-
tive in its own capturing parentheses.
- A name may also be returned after a failed match if the final path
- through the pattern involves (*MARK). However, unless (*MARK) used in
- conjunction with (*COMMIT), this is unlikely to happen for an unan-
- chored pattern because, as the starting point for matching is advanced,
- the final check is often with an empty string, causing a failure before
- (*MARK) is reached. For example:
-
- /X(*MARK:A)Y|X(*MARK:B)Z/K
- XP
- No match
+ If (*MARK) is encountered in a positive assertion, its name is recorded
+ and passed back if it is the last-encountered. This does not happen for
+ negative assertions.
- There are three potential starting points for this match (starting with
- X, starting with P, and with an empty string). If the pattern is
- anchored, the result is different:
+ After a partial match or a failed match, the name of the last encoun-
+ tered (*MARK) in the entire match process is returned. For example:
- /^X(*MARK:A)Y|^X(*MARK:B)Z/K
- XP
+ re> /X(*MARK:A)Y|X(*MARK:B)Z/K
+ data> XP
No match, mark = B
- PCRE's start-of-match optimizations can also interfere with this. For
- example, if, as a result of a call to pcre_study(), it knows the mini-
- mum subject length for a match, a shorter subject will not be scanned
- at all.
-
- Note that similar anomalies (though different in detail) exist in Perl,
- no doubt for the same reasons. The use of (*MARK) data after a failed
- match of an unanchored pattern is not recommended, unless (*COMMIT) is
- involved.
+ Note that in this unanchored example the mark is retained from the
+ match attempt that started at the letter "X" in the subject. Subsequent
+ match attempts starting at "P" and then with an empty string do not get
+ as far as the (*MARK) item, but nevertheless do not reset it.
+
+ If you are interested in (*MARK) values after failed matches, you
+ should probably set the PCRE_NO_START_OPTIMIZE option (see above) to
+ ensure that the match is always attempted.
Verbs that act after backtracking
The following verbs do nothing when they are encountered. Matching con-
- tinues with what follows, but if there is no subsequent match, causing
- a backtrack to the verb, a failure is forced. That is, backtracking
- cannot pass to the left of the verb. However, when one of these verbs
- appears inside an atomic group, its effect is confined to that group,
- because once the group has been matched, there is never any backtrack-
- ing into it. In this situation, backtracking can "jump back" to the
- left of the entire atomic group. (Remember also, as stated above, that
+ tinues with what follows, but if there is no subsequent match, causing
+ a backtrack to the verb, a failure is forced. That is, backtracking
+ cannot pass to the left of the verb. However, when one of these verbs
+ appears inside an atomic group, its effect is confined to that group,
+ because once the group has been matched, there is never any backtrack-
+ ing into it. In this situation, backtracking can "jump back" to the
+ left of the entire atomic group. (Remember also, as stated above, that
this localization also applies in subroutine calls and assertions.)
- These verbs differ in exactly what kind of failure occurs when back-
+ These verbs differ in exactly what kind of failure occurs when back-
tracking reaches them.
(*COMMIT)
- This verb, which may not be followed by a name, causes the whole match
+ This verb, which may not be followed by a name, causes the whole match
to fail outright if the rest of the pattern does not match. Even if the
pattern is unanchored, no further attempts to find a match by advancing
the starting point take place. Once (*COMMIT) has been passed,
- pcre_exec() is committed to finding a match at the current starting
+ pcre_exec() is committed to finding a match at the current starting
point, or not at all. For example:
a+(*COMMIT)b
- This matches "xxaab" but not "aacaab". It can be thought of as a kind
+ This matches "xxaab" but not "aacaab". It can be thought of as a kind
of dynamic anchor, or "I've started, so I must finish." The name of the
- most recently passed (*MARK) in the path is passed back when (*COMMIT)
+ most recently passed (*MARK) in the path is passed back when (*COMMIT)
forces a match failure.
- Note that (*COMMIT) at the start of a pattern is not the same as an
- anchor, unless PCRE's start-of-match optimizations are turned off, as
+ Note that (*COMMIT) at the start of a pattern is not the same as an
+ anchor, unless PCRE's start-of-match optimizations are turned off, as
shown in this pcretest example:
- /(*COMMIT)abc/
- xyzabc
+ re> /(*COMMIT)abc/
+ data> xyzabc
0: abc
xyzabc\Y
No match
- PCRE knows that any match must start with "a", so the optimization
- skips along the subject to "a" before running the first match attempt,
- which succeeds. When the optimization is disabled by the \Y escape in
+ PCRE knows that any match must start with "a", so the optimization
+ skips along the subject to "a" before running the first match attempt,
+ which succeeds. When the optimization is disabled by the \Y escape in
the second subject, the match starts at "x" and so the (*COMMIT) causes
it to fail without trying any other starting points.
(*PRUNE) or (*PRUNE:NAME)
- This verb causes the match to fail at the current starting position in
- the subject if the rest of the pattern does not match. If the pattern
- is unanchored, the normal "bumpalong" advance to the next starting
- character then happens. Backtracking can occur as usual to the left of
- (*PRUNE), before it is reached, or when matching to the right of
- (*PRUNE), but if there is no match to the right, backtracking cannot
- cross (*PRUNE). In simple cases, the use of (*PRUNE) is just an alter-
- native to an atomic group or possessive quantifier, but there are some
+ This verb causes the match to fail at the current starting position in
+ the subject if the rest of the pattern does not match. If the pattern
+ is unanchored, the normal "bumpalong" advance to the next starting
+ character then happens. Backtracking can occur as usual to the left of
+ (*PRUNE), before it is reached, or when matching to the right of
+ (*PRUNE), but if there is no match to the right, backtracking cannot
+ cross (*PRUNE). In simple cases, the use of (*PRUNE) is just an alter-
+ native to an atomic group or possessive quantifier, but there are some
uses of (*PRUNE) that cannot be expressed in any other way. The behav-
- iour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE) when the
- match fails completely; the name is passed back if this is the final
- attempt. (*PRUNE:NAME) does not pass back a name if the match suc-
- ceeds. In an anchored pattern (*PRUNE) has the same effect as (*COM-
- MIT).
+ iour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an
+ anchored pattern (*PRUNE) has the same effect as (*COMMIT).
(*SKIP)
@@ -5637,49 +6405,85 @@
is searched for the most recent (*MARK) that has the same name. If one
is found, the "bumpalong" advance is to the subject position that cor-
responds to that (*MARK) instead of to where (*SKIP) was encountered.
- If no (*MARK) with a matching name is found, normal "bumpalong" of one
- character happens (the (*SKIP) is ignored).
+ If no (*MARK) with a matching name is found, the (*SKIP) is ignored.
(*THEN) or (*THEN:NAME)
- This verb causes a skip to the next alternation in the innermost
- enclosing group if the rest of the pattern does not match. That is, it
- cancels pending backtracking, but only within the current alternation.
- Its name comes from the observation that it can be used for a pattern-
- based if-then-else block:
+ This verb causes a skip to the next innermost alternative if the rest
+ of the pattern does not match. That is, it cancels pending backtrack-
+ ing, but only within the current alternative. Its name comes from the
+ observation that it can be used for a pattern-based if-then-else block:
( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ...
If the COND1 pattern matches, FOO is tried (and possibly further items
- after the end of the group if FOO succeeds); on failure the matcher
+ after the end of the group if FOO succeeds); on failure, the matcher
skips to the second alternative and tries COND2, without backtracking
into COND1. The behaviour of (*THEN:NAME) is exactly the same as
- (*MARK:NAME)(*THEN) if the overall match fails. If (*THEN) is not
- directly inside an alternation, it acts like (*PRUNE).
+ (*MARK:NAME)(*THEN). If (*THEN) is not inside an alternation, it acts
+ like (*PRUNE).
- The above verbs provide four different "strengths" of control when sub-
- sequent matching fails. (*THEN) is the weakest, carrying on the match
- at the next alternation. (*PRUNE) comes next, failing the match at the
- current starting position, but allowing an advance to the next charac-
- ter (for an unanchored pattern). (*SKIP) is similar, except that the
- advance may be more than one character. (*COMMIT) is the strongest,
+ Note that a subpattern that does not contain a | character is just a
+ part of the enclosing alternative; it is not a nested alternation with
+ only one alternative. The effect of (*THEN) extends beyond such a sub-
+ pattern to the enclosing alternative. Consider this pattern, where A,
+ B, etc. are complex pattern fragments that do not contain any | charac-
+ ters at this level:
+
+ A (B(*THEN)C) | D
+
+ If A and B are matched, but there is a failure in C, matching does not
+ backtrack into A; instead it moves to the next alternative, that is, D.
+ However, if the subpattern containing (*THEN) is given an alternative,
+ it behaves differently:
+
+ A (B(*THEN)C | (*FAIL)) | D
+
+ The effect of (*THEN) is now confined to the inner subpattern. After a
+ failure in C, matching moves to (*FAIL), which causes the whole subpat-
+ tern to fail because there are no more alternatives to try. In this
+ case, matching does now backtrack into A.
+
+ Note also that a conditional subpattern is not considered as having two
+ alternatives, because only one is ever used. In other words, the |
+ character in a conditional subpattern has a different meaning. Ignoring
+ white space, consider:
+
+ ^.*? (?(?=a) a | b(*THEN)c )
+
+ If the subject is "ba", this pattern does not match. Because .*? is
+ ungreedy, it initially matches zero characters. The condition (?=a)
+ then fails, the character "b" is matched, but "c" is not. At this
+ point, matching does not backtrack to .*? as might perhaps be expected
+ from the presence of the | character. The conditional subpattern is
+ part of the single alternative that comprises the whole pattern, and so
+ the match fails. (If there was a backtrack into .*?, allowing it to
+ match "b", the match would succeed.)
+
+ The verbs just described provide four different "strengths" of control
+ when subsequent matching fails. (*THEN) is the weakest, carrying on the
+ match at the next alternative. (*PRUNE) comes next, failing the match
+ at the current starting position, but allowing an advance to the next
+ character (for an unanchored pattern). (*SKIP) is similar, except that
+ the advance may be more than one character. (*COMMIT) is the strongest,
causing the entire match to fail.
- If more than one is present in a pattern, the "stongest" one wins. For
- example, consider this pattern, where A, B, etc. are complex pattern
- fragments:
+ If more than one such verb is present in a pattern, the "strongest" one
+ wins. For example, consider this pattern, where A, B, etc. are complex
+ pattern fragments:
(A(*COMMIT)B(*THEN)C|D)
- Once A has matched, PCRE is committed to this match, at the current
- starting position. If subsequently B matches, but C does not, the nor-
- mal (*THEN) action of trying the next alternation (that is, D) does not
+ Once A has matched, PCRE is committed to this match, at the current
+ starting position. If subsequently B matches, but C does not, the nor-
+ mal (*THEN) action of trying the next alternative (that is, D) does not
happen because (*COMMIT) overrides.
SEE ALSO
- pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3).
+ pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3),
+ pcre16(3).
AUTHOR
@@ -5691,8 +6495,8 @@
REVISION
- Last updated: 21 November 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 17 June 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
@@ -5707,7 +6511,7 @@
The full syntax and semantics of the regular expressions that are sup-
ported by PCRE are described in the pcrepattern documentation. This
- document contains just a quick-reference summary of the syntax.
+ document contains a quick-reference summary of the syntax.
QUOTING
@@ -5721,7 +6525,7 @@
\a alarm, that is, the BEL character (hex 07)
\cx "control-x", where x is any ASCII character
\e escape (hex 1B)
- \f formfeed (hex 0C)
+ \f form feed (hex 0C)
\n newline (hex 0A)
\r carriage return (hex 0D)
\t tab (hex 09)
@@ -5734,25 +6538,25 @@
. any character except newline;
in dotall mode, any character whatsoever
- \C one byte, even in UTF-8 mode (best avoided)
+ \C one data unit, even in UTF mode (best avoided)
\d a decimal digit
\D a character that is not a decimal digit
- \h a horizontal whitespace character
- \H a character that is not a horizontal whitespace character
+ \h a horizontal white space character
+ \H a character that is not a horizontal white space character
\N a character that is not a newline
\p{xx} a character with the xx property
\P{xx} a character without the xx property
\R a newline sequence
- \s a whitespace character
- \S a character that is not a whitespace character
- \v a vertical whitespace character
- \V a character that is not a vertical whitespace character
+ \s a white space character
+ \S a character that is not a white space character
+ \v a vertical white space character
+ \V a character that is not a vertical white space character
\w a "word" character
\W a "non-word" character
\X an extended Unicode sequence
In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII
- characters, even in UTF-8 mode. However, this can be changed by setting
+ characters, even in a UTF mode. However, this can be changed by setting
the PCRE_UCP option.
@@ -5814,20 +6618,22 @@
SCRIPT NAMES FOR \p AND \P
- Arabic, Armenian, Avestan, Balinese, Bamum, Bengali, Bopomofo, Braille,
- Buginese, Buhid, Canadian_Aboriginal, Carian, Cham, Cherokee, Common,
- Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyp-
- tian_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek,
- Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Impe-
- rial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscriptional_Parthian,
- Javanese, Kaithi, Kannada, Katakana, Kayah_Li, Kharoshthi, Khmer, Lao,
- Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian, Lydian, Malayalam,
- Meetei_Mayek, Mongolian, Myanmar, New_Tai_Lue, Nko, Ogham, Old_Italic,
- Old_Persian, Old_South_Arabian, Old_Turkic, Ol_Chiki, Oriya, Osmanya,
- Phags_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Shavian,
- Sinhala, Sundanese, Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le,
- Tai_Tham, Tai_Viet, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh,
- Ugaritic, Vai, Yi.
+ Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo,
+ Brahmi, Braille, Buginese, Buhid, Canadian_Aboriginal, Carian, Chakma,
+ Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret,
+ Devanagari, Egyptian_Hieroglyphs, Ethiopic, Georgian, Glagolitic,
+ Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hira-
+ gana, Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip-
+ tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li,
+ Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear_B, Lisu, Lycian,
+ Lydian, Malayalam, Mandaic, Meetei_Mayek, Meroitic_Cursive,
+ Meroitic_Hieroglyphs, Miao, Mongolian, Myanmar, New_Tai_Lue, Nko,
+ Ogham, Old_Italic, Old_Persian, Old_South_Arabian, Old_Turkic,
+ Ol_Chiki, Oriya, Osmanya, Phags_Pa, Phoenician, Rejang, Runic, Samari-
+ tan, Saurashtra, Sharada, Shavian, Sinhala, Sora_Sompeng, Sundanese,
+ Syloti_Nagri, Syriac, Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet,
+ Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai,
+ Yi.
CHARACTER CLASSES
@@ -5848,7 +6654,7 @@
lower lower case letter
print printing, including space
punct printing, excluding alphanumeric
- space whitespace
+ space white space
upper upper case letter
word same as \w
xdigit hexadecimal digit
@@ -5939,7 +6745,8 @@
one of the newline-setting options with similar syntax:
(*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
- (*UTF8) set UTF-8 mode (PCRE_UTF8)
+ (*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8)
+ (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16)
(*UCP) set PCRE_UCP (use Unicode properties for \d etc)
@@ -6008,6 +6815,7 @@
(*ACCEPT) force successful match
(*FAIL) force backtrack; synonym (*F)
+ (*MARK:NAME) set name to be passed back; synonym (*:NAME)
The following act only when a subsequent match failure causes a back-
track to reach them. They all force a match failure, but they differ in
@@ -6016,14 +6824,18 @@
(*COMMIT) overall failure, no advance of starting point
(*PRUNE) advance to next starting character
- (*SKIP) advance start to current matching position
+ (*PRUNE:NAME) equivalent to (*MARK:NAME)(*PRUNE)
+ (*SKIP) advance to current matching position
+ (*SKIP:NAME) advance to position corresponding to an earlier
+ (*MARK:NAME); if not found, the (*SKIP) is ignored
(*THEN) local failure, backtrack to next alternation
+ (*THEN:NAME) equivalent to (*MARK:NAME)(*THEN)
NEWLINE CONVENTIONS
These are recognized only at the very start of the pattern or after a
- (*BSR_...) or (*UTF8) or (*UCP) option.
+ (*BSR_...), (*UTF8), (*UTF16) or (*UCP) option.
(*CR) carriage return only
(*LF) linefeed only
@@ -6035,7 +6847,7 @@
WHAT \R MATCHES
These are recognized only at the very start of the pattern or after a
- (*...) option that sets the newline convention or UTF-8 or UCP mode.
+ (*...) option that sets the newline convention or a UTF or UCP mode.
(*BSR_ANYCRLF) CR, LF, or CRLF
(*BSR_UNICODE) any Unicode newline sequence
@@ -6061,8 +6873,594 @@
REVISION
- Last updated: 21 November 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 10 January 2012
+ Copyright (c) 1997-2012 University of Cambridge.
+------------------------------------------------------------------------------
+
+
+PCREUNICODE(3) PCREUNICODE(3)
+
+
+NAME
+ PCRE - Perl-compatible regular expressions
+
+
+UTF-8, UTF-16, AND UNICODE PROPERTY SUPPORT
+
+ From Release 8.30, in addition to its previous UTF-8 support, PCRE also
+ supports UTF-16 by means of a separate 16-bit library. This can be
+ built as well as, or instead of, the 8-bit library.
+
+
+UTF-8 SUPPORT
+
+ In order process UTF-8 strings, you must build PCRE's 8-bit library
+ with UTF support, and, in addition, you must call pcre_compile() with
+ the PCRE_UTF8 option flag, or the pattern must start with the sequence
+ (*UTF8). When either of these is the case, both the pattern and any
+ subject strings that are matched against it are treated as UTF-8
+ strings instead of strings of 1-byte characters.
+
+
+UTF-16 SUPPORT
+
+ In order process UTF-16 strings, you must build PCRE's 16-bit library
+ with UTF support, and, in addition, you must call pcre16_compile() with
+ the PCRE_UTF16 option flag, or the pattern must start with the sequence
+ (*UTF16). When either of these is the case, both the pattern and any
+ subject strings that are matched against it are treated as UTF-16
+ strings instead of strings of 16-bit characters.
+
+
+UTF SUPPORT OVERHEAD
+
+ If you compile PCRE with UTF support, but do not use it at run time,
+ the library will be a bit bigger, but the additional run time overhead
+ is limited to testing the PCRE_UTF8/16 flag occasionally, so should not
+ be very big.
+
+
+UNICODE PROPERTY SUPPORT
+
+ If PCRE is built with Unicode character property support (which implies
+ UTF support), the escape sequences \p{..}, \P{..}, and \X can be used.
+ The available properties that can be tested are limited to the general
+ category properties such as Lu for an upper case letter or Nd for a
+ decimal number, the Unicode script names such as Arabic or Han, and the
+ derived properties Any and L&. A full list is given in the pcrepattern
+ documentation. Only the short names for properties are supported. For
+ example, \p{L} matches a letter. Its Perl synonym, \p{Letter}, is not
+ supported. Furthermore, in Perl, many properties may optionally be
+ prefixed by "Is", for compatibility with Perl 5.6. PCRE does not sup-
+ port this.
+
+ Validity of UTF-8 strings
+
+ When you set the PCRE_UTF8 flag, the byte strings passed as patterns
+ and subjects are (by default) checked for validity on entry to the rel-
+ evant functions. The entire string is checked before any other process-
+ ing takes place. From release 7.3 of PCRE, the check is according the
+ rules of RFC 3629, which are themselves derived from the Unicode speci-
+ fication. Earlier releases of PCRE followed the rules of RFC 2279,
+ which allows the full range of 31-bit values (0 to 0x7FFFFFFF). The
+ current check allows only values in the range U+0 to U+10FFFF, exclud-
+ ing U+D800 to U+DFFF.
+
+ The excluded code points are the "Surrogate Area" of Unicode. They are
+ reserved for use by UTF-16, where they are used in pairs to encode
+ codepoints with values greater than 0xFFFF. The code points that are
+ encoded by UTF-16 pairs are available independently in the UTF-8 encod-
+ ing. (In other words, the whole surrogate thing is a fudge for UTF-16
+ which unfortunately messes up UTF-8.)
+
+ If an invalid UTF-8 string is passed to PCRE, an error return is given.
+ At compile time, the only additional information is the offset to the
+ first byte of the failing character. The run-time functions pcre_exec()
+ and pcre_dfa_exec() also pass back this information, as well as a more
+ detailed reason code if the caller has provided memory in which to do
+ this.
+
+ In some situations, you may already know that your strings are valid,
+ and therefore want to skip these checks in order to improve perfor-
+ mance, for example in the case of a long subject string that is being
+ scanned repeatedly with different patterns. If you set the
+ PCRE_NO_UTF8_CHECK flag at compile time or at run time, PCRE assumes
+ that the pattern or subject it is given (respectively) contains only
+ valid UTF-8 codes. In this case, it does not diagnose an invalid UTF-8
+ string.
+
+ If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set,
+ what happens depends on why the string is invalid. If the string con-
+ forms to the "old" definition of UTF-8 (RFC 2279), it is processed as a
+ string of characters in the range 0 to 0x7FFFFFFF by pcre_dfa_exec()
+ and the interpreted version of pcre_exec(). In other words, apart from
+ the initial validity test, these functions (when in UTF-8 mode) handle
+ strings according to the more liberal rules of RFC 2279. However, the
+ just-in-time (JIT) optimization for pcre_exec() supports only RFC 3629.
+ If you are using JIT optimization, or if the string does not even con-
+ form to RFC 2279, the result is undefined. Your program may crash.
+
+ If you want to process strings of values in the full range 0 to
+ 0x7FFFFFFF, encoded in a UTF-8-like manner as per the old RFC, you can
+ set PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in
+ this situation, you will have to apply your own validity check, and
+ avoid the use of JIT optimization.
+
+ Validity of UTF-16 strings
+
+ When you set the PCRE_UTF16 flag, the strings of 16-bit data units that
+ are passed as patterns and subjects are (by default) checked for valid-
+ ity on entry to the relevant functions. Values other than those in the
+ surrogate range U+D800 to U+DFFF are independent code points. Values in
+ the surrogate range must be used in pairs in the correct manner.
+
+ If an invalid UTF-16 string is passed to PCRE, an error return is
+ given. At compile time, the only additional information is the offset
+ to the first data unit of the failing character. The run-time functions
+ pcre16_exec() and pcre16_dfa_exec() also pass back this information, as
+ well as a more detailed reason code if the caller has provided memory
+ in which to do this.
+
+ In some situations, you may already know that your strings are valid,
+ and therefore want to skip these checks in order to improve perfor-
+ mance. If you set the PCRE_NO_UTF16_CHECK flag at compile time or at
+ run time, PCRE assumes that the pattern or subject it is given (respec-
+ tively) contains only valid UTF-16 sequences. In this case, it does not
+ diagnose an invalid UTF-16 string.
+
+ General comments about UTF modes
+
+ 1. Codepoints less than 256 can be specified by either braced or
+ unbraced hexadecimal escape sequences (for example, \x{b3} or \xb3).
+ Larger values have to use braced sequences.
+
+ 2. Octal numbers up to \777 are recognized, and in UTF-8 mode, they
+ match two-byte characters for values greater than \177.
+
+ 3. Repeat quantifiers apply to complete UTF characters, not to individ-
+ ual data units, for example: \x{100}{3}.
+
+ 4. The dot metacharacter matches one UTF character instead of a single
+ data unit.
+
+ 5. The escape sequence \C can be used to match a single byte in UTF-8
+ mode, or a single 16-bit data unit in UTF-16 mode, but its use can lead
+ to some strange effects because it breaks up multi-unit characters (see
+ the description of \C in the pcrepattern documentation). The use of \C
+ is not supported in the alternative matching function
+ pcre[16]_dfa_exec(), nor is it supported in UTF mode by the JIT opti-
+ mization of pcre[16]_exec(). If JIT optimization is requested for a UTF
+ pattern that contains \C, it will not succeed, and so the matching will
+ be carried out by the normal interpretive function.
+
+ 6. The character escapes \b, \B, \d, \D, \s, \S, \w, and \W correctly
+ test characters of any code value, but, by default, the characters that
+ PCRE recognizes as digits, spaces, or word characters remain the same
+ set as in non-UTF mode, all with values less than 256. This remains
+ true even when PCRE is built to include Unicode property support,
+ because to do otherwise would slow down PCRE in many common cases. Note
+ in particular that this applies to \b and \B, because they are defined
+ in terms of \w and \W. If you really want to test for a wider sense of,
+ say, "digit", you can use explicit Unicode property tests such as
+ \p{Nd}. Alternatively, if you set the PCRE_UCP option, the way that the
+ character escapes work is changed so that Unicode properties are used
+ to determine which characters match. There are more details in the sec-
+ tion on generic character types in the pcrepattern documentation.
+
+ 7. Similarly, characters that match the POSIX named character classes
+ are all low-valued characters, unless the PCRE_UCP option is set.
+
+ 8. However, the horizontal and vertical white space matching escapes
+ (\h, \H, \v, and \V) do match all the appropriate Unicode characters,
+ whether or not PCRE_UCP is set.
+
+ 9. Case-insensitive matching applies only to characters whose values
+ are less than 128, unless PCRE is built with Unicode property support.
+ Even when Unicode property support is available, PCRE still uses its
+ own character tables when checking the case of low-valued characters,
+ so as not to degrade performance. The Unicode property information is
+ used only for characters with higher values. Furthermore, PCRE supports
+ case-insensitive matching only when there is a one-to-one mapping
+ between a letter's cases. There are a small number of many-to-one map-
+ pings in Unicode; these are not supported by PCRE.
+
+
+AUTHOR
+
+ Philip Hazel
+ University Computing Service
+ Cambridge CB2 3QH, England.
+
+
+REVISION
+
+ Last updated: 14 April 2012
+ Copyright (c) 1997-2012 University of Cambridge.
+------------------------------------------------------------------------------
+
+
+PCREJIT(3) PCREJIT(3)
+
+
+NAME
+ PCRE - Perl-compatible regular expressions
+
+
+PCRE JUST-IN-TIME COMPILER SUPPORT
+
+ Just-in-time compiling is a heavyweight optimization that can greatly
+ speed up pattern matching. However, it comes at the cost of extra pro-
+ cessing before the match is performed. Therefore, it is of most benefit
+ when the same pattern is going to be matched many times. This does not
+ necessarily mean many calls of a matching function; if the pattern is
+ not anchored, matching attempts may take place many times at various
+ positions in the subject, even for a single call. Therefore, if the
+ subject string is very long, it may still pay to use JIT for one-off
+ matches.
+
+ JIT support applies only to the traditional Perl-compatible matching
+ function. It does not apply when the DFA matching function is being
+ used. The code for this support was written by Zoltan Herczeg.
+
+
+8-BIT and 16-BIT SUPPORT
+
+ JIT support is available for both the 8-bit and 16-bit PCRE libraries.
+ To keep this documentation simple, only the 8-bit interface is
+ described in what follows. If you are using the 16-bit library, substi-
+ tute the 16-bit functions and 16-bit structures (for example,
+ pcre16_jit_stack instead of pcre_jit_stack).
+
+
+AVAILABILITY OF JIT SUPPORT
+
+ JIT support is an optional feature of PCRE. The "configure" option
+ --enable-jit (or equivalent CMake option) must be set when PCRE is
+ built if you want to use JIT. The support is limited to the following
+ hardware platforms:
+
+ ARM v5, v7, and Thumb2
+ Intel x86 32-bit and 64-bit
+ MIPS 32-bit
+ Power PC 32-bit and 64-bit
+
+ If --enable-jit is set on an unsupported platform, compilation fails.
+
+ A program that is linked with PCRE 8.20 or later can tell if JIT sup-
+ port is available by calling pcre_config() with the PCRE_CONFIG_JIT
+ option. The result is 1 when JIT is available, and 0 otherwise. How-
+ ever, a simple program does not need to check this in order to use JIT.
+ The API is implemented in a way that falls back to the interpretive
+ code if JIT is not available.
+
+ If your program may sometimes be linked with versions of PCRE that are
+ older than 8.20, but you want to use JIT when it is available, you can
+ test the values of PCRE_MAJOR and PCRE_MINOR, or the existence of a JIT
+ macro such as PCRE_CONFIG_JIT, for compile-time control of your code.
+
+
+SIMPLE USE OF JIT
+
+ You have to do two things to make use of the JIT support in the sim-
+ plest way:
+
+ (1) Call pcre_study() with the PCRE_STUDY_JIT_COMPILE option for
+ each compiled pattern, and pass the resulting pcre_extra block to
+ pcre_exec().
+
+ (2) Use pcre_free_study() to free the pcre_extra block when it is
+ no longer needed, instead of just freeing it yourself. This
+ ensures that any JIT data is also freed.
+
+ For a program that may be linked with pre-8.20 versions of PCRE, you
+ can insert
+
+ #ifndef PCRE_STUDY_JIT_COMPILE
+ #define PCRE_STUDY_JIT_COMPILE 0
+ #endif
+
+ so that no option is passed to pcre_study(), and then use something
+ like this to free the study data:
+
+ #ifdef PCRE_CONFIG_JIT
+ pcre_free_study(study_ptr);
+ #else
+ pcre_free(study_ptr);
+ #endif
+
+ PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for
+ complete matches. If you want to run partial matches using the
+ PCRE_PARTIAL_HARD or PCRE_PARTIAL_SOFT options of pcre_exec(), you
+ should set one or both of the following options in addition to, or
+ instead of, PCRE_STUDY_JIT_COMPILE when you call pcre_study():
+
+ PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
+ PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
+
+ The JIT compiler generates different optimized code for each of the
+ three modes (normal, soft partial, hard partial). When pcre_exec() is
+ called, the appropriate code is run if it is available. Otherwise, the
+ pattern is matched using interpretive code.
+
+ In some circumstances you may need to call additional functions. These
+ are described in the section entitled "Controlling the JIT stack"
+ below.
+
+ If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are
+ ignored, and no JIT data is created. Otherwise, the compiled pattern is
+ passed to the JIT compiler, which turns it into machine code that exe-
+ cutes much faster than the normal interpretive code. When pcre_exec()
+ is passed a pcre_extra block containing a pointer to JIT code of the
+ appropriate mode (normal or hard/soft partial), it obeys that code
+ instead of running the interpreter. The result is identical, but the
+ compiled JIT code runs much faster.
+
+ There are some pcre_exec() options that are not supported for JIT exe-
+ cution. There are also some pattern items that JIT cannot handle.
+ Details are given below. In both cases, execution automatically falls
+ back to the interpretive code. If you want to know whether JIT was
+ actually used for a particular match, you should arrange for a JIT
+ callback function to be set up as described in the section entitled
+ "Controlling the JIT stack" below, even if you do not need to supply a
+ non-default JIT stack. Such a callback function is called whenever JIT
+ code is about to be obeyed. If the execution options are not right for
+ JIT execution, the callback function is not obeyed.
+
+ If the JIT compiler finds an unsupported item, no JIT data is gener-
+ ated. You can find out if JIT execution is available after studying a
+ pattern by calling pcre_fullinfo() with the PCRE_INFO_JIT option. A
+ result of 1 means that JIT compilation was successful. A result of 0
+ means that JIT support is not available, or the pattern was not studied
+ with PCRE_STUDY_JIT_COMPILE etc., or the JIT compiler was not able to
+ handle the pattern.
+
+ Once a pattern has been studied, with or without JIT, it can be used as
+ many times as you like for matching different subject strings.
+
+
+UNSUPPORTED OPTIONS AND PATTERN ITEMS
+
+ The only pcre_exec() options that are supported for JIT execution are
+ PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NOTBOL, PCRE_NOTEOL,
+ PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PAR-
+ TIAL_SOFT.
+
+ The unsupported pattern items are:
+
+ \C match a single byte; not supported in UTF-8 mode
+ (?Cn) callouts
+ (*PRUNE) )
+ (*SKIP) ) backtracking control verbs
+ (*THEN) )
+
+ Support for some of these may be added in future.
+
+
+RETURN VALUES FROM JIT EXECUTION
+
+ When a pattern is matched using JIT execution, the return values are
+ the same as those given by the interpretive pcre_exec() code, with the
+ addition of one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means
+ that the memory used for the JIT stack was insufficient. See "Control-
+ ling the JIT stack" below for a discussion of JIT stack usage. For com-
+ patibility with the interpretive pcre_exec() code, no more than two-
+ thirds of the ovector argument is used for passing back captured sub-
+ strings.
+
+ The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if
+ searching a very large pattern tree goes on for too long, as it is in
+ the same circumstance when JIT is not used, but the details of exactly
+ what is counted are not the same. The PCRE_ERROR_RECURSIONLIMIT error
+ code is never returned by JIT execution.
+
+
+SAVING AND RESTORING COMPILED PATTERNS
+
+ The code that is generated by the JIT compiler is architecture-spe-
+ cific, and is also position dependent. For those reasons it cannot be
+ saved (in a file or database) and restored later like the bytecode and
+ other data of a compiled pattern. Saving and restoring compiled pat-
+ terns is not something many people do. More detail about this facility
+ is given in the pcreprecompile documentation. It should be possible to
+ run pcre_study() on a saved and restored pattern, and thereby recreate
+ the JIT data, but because JIT compilation uses significant resources,
+ it is probably not worth doing this; you might as well recompile the
+ original pattern.
+
+
+CONTROLLING THE JIT STACK
+
+ When the compiled JIT code runs, it needs a block of memory to use as a
+ stack. By default, it uses 32K on the machine stack. However, some
+ large or complicated patterns need more than this. The error
+ PCRE_ERROR_JIT_STACKLIMIT is given when there is not enough stack.
+ Three functions are provided for managing blocks of memory for use as
+ JIT stacks. There is further discussion about the use of JIT stacks in
+ the section entitled "JIT stack FAQ" below.
+
+ The pcre_jit_stack_alloc() function creates a JIT stack. Its arguments
+ are a starting size and a maximum size, and it returns a pointer to an
+ opaque structure of type pcre_jit_stack, or NULL if there is an error.
+ The pcre_jit_stack_free() function can be used to free a stack that is
+ no longer needed. (For the technically minded: the address space is
+ allocated by mmap or VirtualAlloc.)
+
+ JIT uses far less memory for recursion than the interpretive code, and
+ a maximum stack size of 512K to 1M should be more than enough for any
+ pattern.
+
+ The pcre_assign_jit_stack() function specifies which stack JIT code
+ should use. Its arguments are as follows:
+
+ pcre_extra *extra
+ pcre_jit_callback callback
+ void *data
+
+ The extra argument must be the result of studying a pattern with
+ PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the
+ other two options:
+
+ (1) If callback is NULL and data is NULL, an internal 32K block
+ on the machine stack is used.
+
+ (2) If callback is NULL and data is not NULL, data must be
+ a valid JIT stack, the result of calling pcre_jit_stack_alloc().
+
+ (3) If callback is not NULL, it must point to a function that is
+ called with data as an argument at the start of matching, in
+ order to set up a JIT stack. If the return from the callback
+ function is NULL, the internal 32K stack is used; otherwise the
+ return value must be a valid JIT stack, the result of calling
+ pcre_jit_stack_alloc().
+
+ A callback function is obeyed whenever JIT code is about to be run; it
+ is not obeyed when pcre_exec() is called with options that are incom-
+ patible for JIT execution. A callback function can therefore be used to
+ determine whether a match operation was executed by JIT or by the
+ interpreter.
+
+ You may safely use the same JIT stack for more than one pattern (either
+ by assigning directly or by callback), as long as the patterns are all
+ matched sequentially in the same thread. In a multithread application,
+ if you do not specify a JIT stack, or if you assign or pass back NULL
+ from a callback, that is thread-safe, because each thread has its own
+ machine stack. However, if you assign or pass back a non-NULL JIT
+ stack, this must be a different stack for each thread so that the
+ application is thread-safe.
+
+ Strictly speaking, even more is allowed. You can assign the same non-
+ NULL stack to any number of patterns as long as they are not used for
+ matching by multiple threads at the same time. For example, you can
+ assign the same stack to all compiled patterns, and use a global mutex
+ in the callback to wait until the stack is available for use. However,
+ this is an inefficient solution, and not recommended.
+
+ This is a suggestion for how a multithreaded program that needs to set
+ up non-default JIT stacks might operate:
+
+ During thread initalization
+ thread_local_var = pcre_jit_stack_alloc(...)
+
+ During thread exit
+ pcre_jit_stack_free(thread_local_var)
+
+ Use a one-line callback function
+ return thread_local_var
+
+ All the functions described in this section do nothing if JIT is not
+ available, and pcre_assign_jit_stack() does nothing unless the extra
+ argument is non-NULL and points to a pcre_extra block that is the
+ result of a successful study with PCRE_STUDY_JIT_COMPILE etc.
+
+
+JIT STACK FAQ
+
+ (1) Why do we need JIT stacks?
+
+ PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack
+ where the local data of the current node is pushed before checking its
+ child nodes. Allocating real machine stack on some platforms is diffi-
+ cult. For example, the stack chain needs to be updated every time if we
+ extend the stack on PowerPC. Although it is possible, its updating
+ time overhead decreases performance. So we do the recursion in memory.
+
+ (2) Why don't we simply allocate blocks of memory with malloc()?
+
+ Modern operating systems have a nice feature: they can reserve an
+ address space instead of allocating memory. We can safely allocate mem-
+ ory pages inside this address space, so the stack could grow without
+ moving memory data (this is important because of pointers). Thus we can
+ allocate 1M address space, and use only a single memory page (usually
+ 4K) if that is enough. However, we can still grow up to 1M anytime if
+ needed.
+
+ (3) Who "owns" a JIT stack?
+
+ The owner of the stack is the user program, not the JIT studied pattern
+ or anything else. The user program must ensure that if a stack is used
+ by pcre_exec(), (that is, it is assigned to the pattern currently run-
+ ning), that stack must not be used by any other threads (to avoid over-
+ writing the same memory area). The best practice for multithreaded pro-
+ grams is to allocate a stack for each thread, and return this stack
+ through the JIT callback function.
+
+ (4) When should a JIT stack be freed?
+
+ You can free a JIT stack at any time, as long as it will not be used by
+ pcre_exec() again. When you assign the stack to a pattern, only a
+ pointer is set. There is no reference counting or any other magic. You
+ can free the patterns and stacks in any order, anytime. Just do not
+ call pcre_exec() with a pattern pointing to an already freed stack, as
+ that will cause SEGFAULT. (Also, do not free a stack currently used by
+ pcre_exec() in another thread). You can also replace the stack for a
+ pattern at any time. You can even free the previous stack before
+ assigning a replacement.
+
+ (5) Should I allocate/free a stack every time before/after calling
+ pcre_exec()?
+
+ No, because this is too costly in terms of resources. However, you
+ could implement some clever idea which release the stack if it is not
+ used in let's say two minutes. The JIT callback can help to achive this
+ without keeping a list of the currently JIT studied patterns.
+
+ (6) OK, the stack is for long term memory allocation. But what happens
+ if a pattern causes stack overflow with a stack of 1M? Is that 1M kept
+ until the stack is freed?
+
+ Especially on embedded sytems, it might be a good idea to release mem-
+ ory sometimes without freeing the stack. There is no API for this at
+ the moment. Probably a function call which returns with the currently
+ allocated memory for any stack and another which allows releasing mem-
+ ory (shrinking the stack) would be a good idea if someone needs this.
+
+ (7) This is too much of a headache. Isn't there any better solution for
+ JIT stack handling?
+
+ No, thanks to Windows. If POSIX threads were used everywhere, we could
+ throw out this complicated API.
+
+
+EXAMPLE CODE
+
+ This is a single-threaded example that specifies a JIT stack without
+ using a callback.
+
+ int rc;
+ int ovector[30];
+ pcre *re;
+ pcre_extra *extra;
+ pcre_jit_stack *jit_stack;
+
+ re = pcre_compile(pattern, 0, &error, &erroffset, NULL);
+ /* Check for errors */
+ extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &error);
+ jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024);
+ /* Check for error (NULL) */
+ pcre_assign_jit_stack(extra, NULL, jit_stack);
+ rc = pcre_exec(re, extra, subject, length, 0, 0, ovector, 30);
+ /* Check results */
+ pcre_free(re);
+ pcre_free_study(extra);
+ pcre_jit_stack_free(jit_stack);
+
+
+SEE ALSO
+
+ pcreapi(3)
+
+
+AUTHOR
+
+ Philip Hazel (FAQ by Zoltan Herczeg)
+ University Computing Service
+ Cambridge CB2 3QH, England.
+
+
+REVISION
+
+ Last updated: 04 May 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
@@ -6075,11 +7473,11 @@
PARTIAL MATCHING IN PCRE
- In normal use of PCRE, if the subject string that is passed to
- pcre_exec() or pcre_dfa_exec() matches as far as it goes, but is too
- short to match the entire pattern, PCRE_ERROR_NOMATCH is returned.
- There are circumstances where it might be helpful to distinguish this
- case from other cases in which there is no match.
+ In normal use of PCRE, if the subject string that is passed to a match-
+ ing function matches as far as it goes, but is too short to match the
+ entire pattern, PCRE_ERROR_NOMATCH is returned. There are circumstances
+ where it might be helpful to distinguish this case from other cases in
+ which there is no match.
Consider, for example, an application where a human is required to type
in data for a field with specific formatting requirements. An example
@@ -6097,41 +7495,52 @@
available at once.
PCRE supports partial matching by means of the PCRE_PARTIAL_SOFT and
- PCRE_PARTIAL_HARD options, which can be set when calling pcre_exec() or
- pcre_dfa_exec(). For backwards compatibility, PCRE_PARTIAL is a synonym
- for PCRE_PARTIAL_SOFT. The essential difference between the two options
- is whether or not a partial match is preferred to an alternative com-
- plete match, though the details differ between the two matching func-
- tions. If both options are set, PCRE_PARTIAL_HARD takes precedence.
-
- Setting a partial matching option disables two of PCRE's optimizations.
- PCRE remembers the last literal byte in a pattern, and abandons match-
- ing immediately if such a byte is not present in the subject string.
- This optimization cannot be used for a subject string that might match
- only partially. If the pattern was studied, PCRE knows the minimum
- length of a matching string, and does not bother to run the matching
- function on shorter strings. This optimization is also disabled for
- partial matching.
-
-
-PARTIAL MATCHING USING pcre_exec()
-
- A partial match occurs during a call to pcre_exec() when the end of the
- subject string is reached successfully, but matching cannot continue
- because more characters are needed. However, at least one character in
- the subject must have been inspected. This character need not form part
- of the final matched string; lookbehind assertions and the \K escape
- sequence provide ways of inspecting characters before the start of a
- matched substring. The requirement for inspecting at least one charac-
- ter exists because an empty string can always be matched; without such
- a restriction there would always be a partial match of an empty string
- at the end of the subject.
-
- If there are at least two slots in the offsets vector when pcre_exec()
- returns with a partial match, the first slot is set to the offset of
- the earliest character that was inspected when the partial match was
- found. For convenience, the second offset points to the end of the sub-
- ject so that a substring can easily be identified.
+ PCRE_PARTIAL_HARD options, which can be set when calling any of the
+ matching functions. For backwards compatibility, PCRE_PARTIAL is a syn-
+ onym for PCRE_PARTIAL_SOFT. The essential difference between the two
+ options is whether or not a partial match is preferred to an alterna-
+ tive complete match, though the details differ between the two types of
+ matching function. If both options are set, PCRE_PARTIAL_HARD takes
+ precedence.
+
+ If you want to use partial matching with just-in-time optimized code,
+ you must call pcre_study() or pcre16_study() with one or both of these
+ options:
+
+ PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
+ PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
+
+ PCRE_STUDY_JIT_COMPILE should also be set if you are going to run non-
+ partial matches on the same pattern. If the appropriate JIT study mode
+ has not been set for a match, the interpretive matching code is used.
+
+ Setting a partial matching option disables two of PCRE's standard opti-
+ mizations. PCRE remembers the last literal data unit in a pattern, and
+ abandons matching immediately if it is not present in the subject
+ string. This optimization cannot be used for a subject string that
+ might match only partially. If the pattern was studied, PCRE knows the
+ minimum length of a matching string, and does not bother to run the
+ matching function on shorter strings. This optimization is also dis-
+ abled for partial matching.
+
+
+PARTIAL MATCHING USING pcre_exec() OR pcre16_exec()
+
+ A partial match occurs during a call to pcre_exec() or pcre16_exec()
+ when the end of the subject string is reached successfully, but match-
+ ing cannot continue because more characters are needed. However, at
+ least one character in the subject must have been inspected. This char-
+ acter need not form part of the final matched string; lookbehind asser-
+ tions and the \K escape sequence provide ways of inspecting characters
+ before the start of a matched substring. The requirement for inspecting
+ at least one character exists because an empty string can always be
+ matched; without such a restriction there would always be a partial
+ match of an empty string at the end of the subject.
+
+ If there are at least two slots in the offsets vector when a partial
+ match is returned, the first slot is set to the offset of the earliest
+ character that was inspected. For convenience, the second offset points
+ to the end of the subject so that a substring can easily be identified.
For the majority of patterns, the first offset identifies the start of
the partially matched string. However, for patterns that contain look-
@@ -6148,13 +7557,13 @@
What happens when a partial match is identified depends on which of the
two partial matching options are set.
- PCRE_PARTIAL_SOFT with pcre_exec()
+ PCRE_PARTIAL_SOFT WITH pcre_exec() OR pcre16_exec()
- If PCRE_PARTIAL_SOFT is set when pcre_exec() identifies a partial
- match, the partial match is remembered, but matching continues as nor-
- mal, and other alternatives in the pattern are tried. If no complete
- match can be found, pcre_exec() returns PCRE_ERROR_PARTIAL instead of
- PCRE_ERROR_NOMATCH.
+ If PCRE_PARTIAL_SOFT is set when pcre_exec() or pcre16_exec() identi-
+ fies a partial match, the partial match is remembered, but matching
+ continues as normal, and other alternatives in the pattern are tried.
+ If no complete match can be found, PCRE_ERROR_PARTIAL is returned
+ instead of PCRE_ERROR_NOMATCH.
This option is "soft" because it prefers a complete match over a par-
tial match. All the various matching items in a pattern behave as if
@@ -6174,22 +7583,24 @@
(In this example, there are two partial matches, because "dog" on its
own partially matches the second alternative.)
- PCRE_PARTIAL_HARD with pcre_exec()
+ PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre16_exec()
- If PCRE_PARTIAL_HARD is set for pcre_exec(), it returns PCRE_ERROR_PAR-
- TIAL as soon as a partial match is found, without continuing to search
- for possible complete matches. This option is "hard" because it prefers
- an earlier partial match over a later complete match. For this reason,
- the assumption is made that the end of the supplied subject string may
- not be the true end of the available data, and so, if \z, \Z, \b, \B,
- or $ are encountered at the end of the subject, the result is
- PCRE_ERROR_PARTIAL.
-
- Setting PCRE_PARTIAL_HARD also affects the way pcre_exec() checks UTF-8
- subject strings for validity. Normally, an invalid UTF-8 sequence
- causes the error PCRE_ERROR_BADUTF8. However, in the special case of a
- truncated UTF-8 character at the end of the subject, PCRE_ERROR_SHORT-
- UTF8 is returned when PCRE_PARTIAL_HARD is set.
+ If PCRE_PARTIAL_HARD is set for pcre_exec() or pcre16_exec(),
+ PCRE_ERROR_PARTIAL is returned as soon as a partial match is found,
+ without continuing to search for possible complete matches. This option
+ is "hard" because it prefers an earlier partial match over a later com-
+ plete match. For this reason, the assumption is made that the end of
+ the supplied subject string may not be the true end of the available
+ data, and so, if \z, \Z, \b, \B, or $ are encountered at the end of the
+ subject, the result is PCRE_ERROR_PARTIAL, provided that at least one
+ character in the subject has been inspected.
+
+ Setting PCRE_PARTIAL_HARD also affects the way UTF-8 and UTF-16 subject
+ strings are checked for validity. Normally, an invalid sequence causes
+ the error PCRE_ERROR_BADUTF8 or PCRE_ERROR_BADUTF16. However, in the
+ special case of a truncated character at the end of the subject,
+ PCRE_ERROR_SHORTUTF8 or PCRE_ERROR_SHORTUTF16 is returned when
+ PCRE_PARTIAL_HARD is set.
Comparing hard and soft partial matching
@@ -6207,25 +7618,25 @@
/dog(sbody)??/
- In this case the result is always a complete match because pcre_exec()
- finds that first, and it never continues after finding a match. It
- might be easier to follow this explanation by thinking of the two pat-
- terns like this:
+ In this case the result is always a complete match because that is
+ found first, and matching never continues after finding a complete
+ match. It might be easier to follow this explanation by thinking of the
+ two patterns like this:
/dog(sbody)?/ is the same as /dogsbody|dog/
/dog(sbody)??/ is the same as /dog|dogsbody/
- The second pattern will never match "dogsbody" when pcre_exec() is
- used, because it will always find the shorter match first.
+ The second pattern will never match "dogsbody", because it will always
+ find the shorter match first.
-PARTIAL MATCHING USING pcre_dfa_exec()
+PARTIAL MATCHING USING pcre_dfa_exec() OR pcre16_dfa_exec()
- The pcre_dfa_exec() function moves along the subject string character
- by character, without backtracking, searching for all possible matches
- simultaneously. If the end of the subject is reached before the end of
- the pattern, there is the possibility of a partial match, again pro-
- vided that at least one character has been inspected.
+ The DFA functions move along the subject string character by character,
+ without backtracking, searching for all possible matches simultane-
+ ously. If the end of the subject is reached before the end of the pat-
+ tern, there is the possibility of a partial match, again provided that
+ at least one character has been inspected.
When PCRE_PARTIAL_SOFT is set, PCRE_ERROR_PARTIAL is returned only if
there have been no complete matches. Otherwise, the complete matches
@@ -6235,17 +7646,17 @@
the first matching string, provided there are at least two slots in the
offsets vector.
- Because pcre_dfa_exec() always searches for all possible matches, and
- there is no difference between greedy and ungreedy repetition, its be-
- haviour is different from pcre_exec when PCRE_PARTIAL_HARD is set. Con-
- sider the string "dog" matched against the ungreedy pattern shown
- above:
+ Because the DFA functions always search for all possible matches, and
+ there is no difference between greedy and ungreedy repetition, their
+ behaviour is different from the standard functions when PCRE_PAR-
+ TIAL_HARD is set. Consider the string "dog" matched against the
+ ungreedy pattern shown above:
/dog(sbody)??/
- Whereas pcre_exec() stops as soon as it finds the complete match for
- "dog", pcre_dfa_exec() also finds the partial match for "dogsbody", and
- so returns that when PCRE_PARTIAL_HARD is set.
+ Whereas the standard functions stop as soon as they find the complete
+ match for "dog", the DFA functions also find the partial match for
+ "dogsbody", and so return that when PCRE_PARTIAL_HARD is set.
PARTIAL MATCHING AND WORD BOUNDARIES
@@ -6259,37 +7670,34 @@
This matches "cat", provided there is a word boundary at either end. If
the subject string is "the cat", the comparison of the final "t" with a
following character cannot take place, so a partial match is found.
- However, pcre_exec() carries on with normal matching, which matches \b
- at the end of the subject when the last character is a letter, thus
- finding a complete match. The result, therefore, is not PCRE_ERROR_PAR-
- TIAL. The same thing happens with pcre_dfa_exec(), because it also
- finds the complete match.
-
- Using PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL,
- because then the partial match takes precedence.
+ However, normal matching carries on, and \b matches at the end of the
+ subject when the last character is a letter, so a complete match is
+ found. The result, therefore, is not PCRE_ERROR_PARTIAL. Using
+ PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, because
+ then the partial match takes precedence.
FORMERLY RESTRICTED PATTERNS
For releases of PCRE prior to 8.00, because of the way certain internal
- optimizations were implemented in the pcre_exec() function, the
- PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be
- used with all patterns. From release 8.00 onwards, the restrictions no
- longer apply, and partial matching with pcre_exec() can be requested
- for any pattern.
+ optimizations were implemented in the pcre_exec() function, the
+ PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be
+ used with all patterns. From release 8.00 onwards, the restrictions no
+ longer apply, and partial matching with can be requested for any pat-
+ tern.
Items that were formerly restricted were repeated single characters and
- repeated metasequences. If PCRE_PARTIAL was set for a pattern that did
- not conform to the restrictions, pcre_exec() returned the error code
- PCRE_ERROR_BADPARTIAL (-13). This error code is no longer in use. The
- PCRE_INFO_OKPARTIAL call to pcre_fullinfo() to find out if a compiled
+ repeated metasequences. If PCRE_PARTIAL was set for a pattern that did
+ not conform to the restrictions, pcre_exec() returned the error code
+ PCRE_ERROR_BADPARTIAL (-13). This error code is no longer in use. The
+ PCRE_INFO_OKPARTIAL call to pcre_fullinfo() to find out if a compiled
pattern can be used for partial matching now always returns 1.
EXAMPLE OF PARTIAL MATCHING USING PCRETEST
- If the escape sequence \P is present in a pcretest data line, the
- PCRE_PARTIAL_SOFT option is used for the match. Here is a run of
+ If the escape sequence \P is present in a pcretest data line, the
+ PCRE_PARTIAL_SOFT option is used for the match. Here is a run of
pcretest that uses the date example quoted above:
re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/
@@ -6305,25 +7713,25 @@
data> j\P
No match
- The first data string is matched completely, so pcretest shows the
- matched substrings. The remaining four strings do not match the com-
+ The first data string is matched completely, so pcretest shows the
+ matched substrings. The remaining four strings do not match the com-
plete pattern, but the first two are partial matches. Similar output is
- obtained when pcre_dfa_exec() is used.
+ obtained if DFA matching is used.
- If the escape sequence \P is present more than once in a pcretest data
+ If the escape sequence \P is present more than once in a pcretest data
line, the PCRE_PARTIAL_HARD option is set for the match.
-MULTI-SEGMENT MATCHING WITH pcre_dfa_exec()
+MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre16_dfa_exec()
- When a partial match has been found using pcre_dfa_exec(), it is possi-
- ble to continue the match by providing additional subject data and
- calling pcre_dfa_exec() again with the same compiled regular expres-
- sion, this time setting the PCRE_DFA_RESTART option. You must pass the
+ When a partial match has been found using a DFA matching function, it
+ is possible to continue the match by providing additional subject data
+ and calling the function again with the same compiled regular expres-
+ sion, this time setting the PCRE_DFA_RESTART option. You must pass the
same working space as before, because this is where details of the pre-
- vious partial match are stored. Here is an example using pcretest,
- using the \R escape sequence to set the PCRE_DFA_RESTART option (\D
- specifies the use of pcre_dfa_exec()):
+ vious partial match are stored. Here is an example using pcretest,
+ using the \R escape sequence to set the PCRE_DFA_RESTART option (\D
+ specifies the use of the DFA matching function):
re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/
data> 23ja\P\D
@@ -6331,46 +7739,49 @@
data> n05\R\D
0: n05
- The first call has "23ja" as the subject, and requests partial match-
- ing; the second call has "n05" as the subject for the continued
- (restarted) match. Notice that when the match is complete, only the
- last part is shown; PCRE does not retain the previously partially-
- matched string. It is up to the calling program to do that if it needs
+ The first call has "23ja" as the subject, and requests partial match-
+ ing; the second call has "n05" as the subject for the continued
+ (restarted) match. Notice that when the match is complete, only the
+ last part is shown; PCRE does not retain the previously partially-
+ matched string. It is up to the calling program to do that if it needs
to.
- You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with
- PCRE_DFA_RESTART to continue partial matching over multiple segments.
- This facility can be used to pass very long subject strings to
- pcre_dfa_exec().
-
-
-MULTI-SEGMENT MATCHING WITH pcre_exec()
-
- From release 8.00, pcre_exec() can also be used to do multi-segment
- matching. Unlike pcre_dfa_exec(), it is not possible to restart the
- previous match with a new segment of data. Instead, new data must be
- added to the previous subject string, and the entire match re-run,
- starting from the point where the partial match occurred. Earlier data
- can be discarded. It is best to use PCRE_PARTIAL_HARD in this situa-
- tion, because it does not treat the end of a segment as the end of the
- subject when matching \z, \Z, \b, \B, and $. Consider an unanchored
- pattern that matches dates:
+ You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with
+ PCRE_DFA_RESTART to continue partial matching over multiple segments.
+ This facility can be used to pass very long subject strings to the DFA
+ matching functions.
+
+
+MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre16_exec()
+
+ From release 8.00, the standard matching functions can also be used to
+ do multi-segment matching. Unlike the DFA functions, it is not possible
+ to restart the previous match with a new segment of data. Instead, new
+ data must be added to the previous subject string, and the entire match
+ re-run, starting from the point where the partial match occurred. Ear-
+ lier data can be discarded.
+
+ It is best to use PCRE_PARTIAL_HARD in this situation, because it does
+ not treat the end of a segment as the end of the subject when matching
+ \z, \Z, \b, \B, and $. Consider an unanchored pattern that matches
+ dates:
re> /\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d/
data> The date is 23ja\P\P
Partial match: 23ja
- At this stage, an application could discard the text preceding "23ja",
- add on text from the next segment, and call pcre_exec() again. Unlike
- pcre_dfa_exec(), the entire matching string must always be available,
- and the complete matching process occurs for each call, so more memory
- and more processing time is needed.
-
- Note: If the pattern contains lookbehind assertions, or \K, or starts
- with \b or \B, the string that is returned for a partial match will
- include characters that precede the partially matched string itself,
- because these must be retained when adding on more characters for a
- subsequent matching attempt.
+ At this stage, an application could discard the text preceding "23ja",
+ add on text from the next segment, and call the matching function
+ again. Unlike the DFA matching functions, the entire matching string
+ must always be available, and the complete matching process occurs for
+ each call, so more memory and more processing time is needed.
+
+ Note: If the pattern contains lookbehind assertions, or \K, or starts
+ with \b or \B, the string that is returned for a partial match includes
+ characters that precede the partially matched string itself, because
+ these must be retained when adding on more characters for a subsequent
+ matching attempt. However, in some cases you may need to retain even
+ earlier characters, as discussed in the next section.
ISSUES WITH MULTI-SEGMENT MATCHING
@@ -6384,23 +7795,40 @@
option, but in practice when doing multi-segment matching you should be
using PCRE_PARTIAL_HARD, which includes the effect of PCRE_NOTEOL.
- 2. Lookbehind assertions at the start of a pattern are catered for in
- the offsets that are returned for a partial match. However, in theory,
- a lookbehind assertion later in the pattern could require even earlier
- characters to be inspected, and it might not have been reached when a
- partial match occurs. This is probably an extremely unlikely case; you
- could guard against it to a certain extent by always including extra
- characters at the start.
-
- 3. Matching a subject string that is split into multiple segments may
- not always produce exactly the same result as matching over one single
- long string, especially when PCRE_PARTIAL_SOFT is used. The section
- "Partial Matching and Word Boundaries" above describes an issue that
- arises if the pattern ends with \b or \B. Another kind of difference
- may occur when there are multiple matching possibilities, because (for
- PCRE_PARTIAL_SOFT) a partial match result is given only when there are
+ 2. Lookbehind assertions that have already been obeyed are catered for
+ in the offsets that are returned for a partial match. However a lookbe-
+ hind assertion later in the pattern could require even earlier charac-
+ ters to be inspected. You can handle this case by using the
+ PCRE_INFO_MAXLOOKBEHIND option of the pcre_fullinfo() or
+ pcre16_fullinfo() functions to obtain the length of the largest lookbe-
+ hind in the pattern. This length is given in characters, not bytes. If
+ you always retain at least that many characters before the partially
+ matched string, all should be well. (Of course, near the start of the
+ subject, fewer characters may be present; in that case all characters
+ should be retained.)
+
+ 3. Because a partial match must always contain at least one character,
+ what might be considered a partial match of an empty string actually
+ gives a "no match" result. For example:
+
+ re> /c(?<=abc)x/
+ data> ab\P
+ No match
+
+ If the next segment begins "cx", a match should be found, but this will
+ only happen if characters from the previous segment are retained. For
+ this reason, a "no match" result should be interpreted as "partial
+ match of an empty string" when the pattern contains lookbehinds.
+
+ 4. Matching a subject string that is split into multiple segments may
+ not always produce exactly the same result as matching over one single
+ long string, especially when PCRE_PARTIAL_SOFT is used. The section
+ "Partial Matching and Word Boundaries" above describes an issue that
+ arises if the pattern ends with \b or \B. Another kind of difference
+ may occur when there are multiple matching possibilities, because (for
+ PCRE_PARTIAL_SOFT) a partial match result is given only when there are
no completed matches. This means that as soon as the shortest match has
- been found, continuation to a new subject segment is no longer possi-
+ been found, continuation to a new subject segment is no longer possi-
ble. Consider again this pcretest example:
re> /dog(sbody)?/
@@ -6414,14 +7842,15 @@
0: dogsbody
1: dog
- The first data line passes the string "dogsb" to pcre_exec(), setting
- the PCRE_PARTIAL_SOFT option. Although the string is a partial match
- for "dogsbody", the result is not PCRE_ERROR_PARTIAL, because the
- shorter string "dog" is a complete match. Similarly, when the subject
- is presented to pcre_dfa_exec() in several parts ("do" and "gsb" being
- the first two) the match stops when "dog" has been found, and it is not
- possible to continue. On the other hand, if "dogsbody" is presented as
- a single string, pcre_dfa_exec() finds both matches.
+ The first data line passes the string "dogsb" to a standard matching
+ function, setting the PCRE_PARTIAL_SOFT option. Although the string is
+ a partial match for "dogsbody", the result is not PCRE_ERROR_PARTIAL,
+ because the shorter string "dog" is a complete match. Similarly, when
+ the subject is presented to a DFA matching function in several parts
+ ("do" and "gsb" being the first two) the match stops when "dog" has
+ been found, and it is not possible to continue. On the other hand, if
+ "dogsbody" is presented as a single string, a DFA matching function
+ finds both matches.
Because of these problems, it is best to use PCRE_PARTIAL_HARD when
matching multi-segment data. The example above then behaves differ-
@@ -6435,28 +7864,27 @@
data> gsb\R\P\P\D
Partial match: gsb
- 4. Patterns that contain alternatives at the top level which do not all
+ 5. Patterns that contain alternatives at the top level which do not all
start with the same pattern item may not work as expected when
- PCRE_DFA_RESTART is used with pcre_dfa_exec(). For example, consider
- this pattern:
+ PCRE_DFA_RESTART is used. For example, consider this pattern:
1234|3789
- If the first part of the subject is "ABC123", a partial match of the
- first alternative is found at offset 3. There is no partial match for
+ If the first part of the subject is "ABC123", a partial match of the
+ first alternative is found at offset 3. There is no partial match for
the second alternative, because such a match does not start at the same
- point in the subject string. Attempting to continue with the string
- "7890" does not yield a match because only those alternatives that
- match at one point in the subject are remembered. The problem arises
- because the start of the second alternative matches within the first
- alternative. There is no problem with anchored patterns or patterns
+ point in the subject string. Attempting to continue with the string
+ "7890" does not yield a match because only those alternatives that
+ match at one point in the subject are remembered. The problem arises
+ because the start of the second alternative matches within the first
+ alternative. There is no problem with anchored patterns or patterns
such as:
1234|ABCD
- where no string can be a partial match for both alternatives. This is
- not a problem if pcre_exec() is used, because the entire match has to
- be rerun each time:
+ where no string can be a partial match for both alternatives. This is
+ not a problem if a standard matching function is used, because the
+ entire match has to be rerun each time:
re> /1234|3789/
data> ABC123\P\P
@@ -6465,11 +7893,11 @@
0: 3789
Of course, instead of using PCRE_DFA_RESTART, the same technique of re-
- running the entire match can also be used with pcre_dfa_exec(). Another
- possibility is to work with two buffers. If a partial match at offset n
- in the first buffer is followed by "no match" when PCRE_DFA_RESTART is
- used on the second buffer, you can then try a new match starting at
- offset n+1 in the first buffer.
+ running the entire match can also be used with the DFA matching func-
+ tions. Another possibility is to work with two buffers. If a partial
+ match at offset n in the first buffer is followed by "no match" when
+ PCRE_DFA_RESTART is used on the second buffer, you can then try a new
+ match starting at offset n+1 in the first buffer.
AUTHOR
@@ -6481,8 +7909,8 @@
REVISION
- Last updated: 07 November 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 24 February 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
@@ -6500,26 +7928,32 @@
form instead of having to compile them every time the application is
run. If you are not using any private character tables (see the
pcre_maketables() documentation), this is relatively straightforward.
- If you are using private tables, it is a little bit more complicated.
+ If you are using private tables, it is a little bit more complicated.
+ However, if you are using the just-in-time optimization feature, it is
+ not possible to save and reload the JIT data.
If you save compiled patterns to a file, you can copy them to a differ-
- ent host and run them there. This works even if the new host has the
- opposite endianness to the one on which the patterns were compiled.
- There may be a small performance penalty, but it should be insignifi-
- cant. However, compiling regular expressions with one version of PCRE
- for use with a different version is not guaranteed to work and may
- cause crashes.
+ ent host and run them there. If the two hosts have different endianness
+ (byte order), you should run the pcre[16]_pattern_to_host_byte_order()
+ function on the new host before trying to match the pattern. The match-
+ ing functions return PCRE_ERROR_BADENDIANNESS if they detect a pattern
+ with the wrong endianness.
+
+ Compiling regular expressions with one version of PCRE for use with a
+ different version is not guaranteed to work and may cause crashes, and
+ saving and restoring a compiled pattern loses any JIT optimization
+ data.
SAVING A COMPILED PATTERN
- The value returned by pcre_compile() points to a single block of memory
- that holds the compiled pattern and associated data. You can find the
- length of this block in bytes by calling pcre_fullinfo() with an argu-
- ment of PCRE_INFO_SIZE. You can then save the data in any appropriate
- manner. Here is sample code that compiles a pattern and writes it to a
- file. It assumes that the variable fd refers to a file that is open for
- output:
+ The value returned by pcre[16]_compile() points to a single block of
+ memory that holds the compiled pattern and associated data. You can
+ find the length of this block in bytes by calling pcre[16]_fullinfo()
+ with an argument of PCRE_INFO_SIZE. You can then save the data in any
+ appropriate manner. Here is sample code for the 8-bit library that com-
+ piles a pattern and writes it to a file. It assumes that the variable
+ fd refers to a file that is open for output:
int erroroffset, rc, size;
char *error;
@@ -6549,45 +7983,49 @@
in the memory of some daemon process that passes them via sockets to
the processes that want them.
- If the pattern has been studied, it is also possible to save the study
- data in a similar way to the compiled pattern itself. When studying
- generates additional information, pcre_study() returns a pointer to a
- pcre_extra data block. Its format is defined in the section on matching
- a pattern in the pcreapi documentation. The study_data field points to
- the binary study data, and this is what you must save (not the
- pcre_extra block itself). The length of the study data can be obtained
- by calling pcre_fullinfo() with an argument of PCRE_INFO_STUDYSIZE.
- Remember to check that pcre_study() did return a non-NULL value before
- trying to save the study data.
+ If the pattern has been studied, it is also possible to save the normal
+ study data in a similar way to the compiled pattern itself. However, if
+ the PCRE_STUDY_JIT_COMPILE was used, the just-in-time data that is cre-
+ ated cannot be saved because it is too dependent on the current envi-
+ ronment. When studying generates additional information,
+ pcre[16]_study() returns a pointer to a pcre[16]_extra data block. Its
+ format is defined in the section on matching a pattern in the pcreapi
+ documentation. The study_data field points to the binary study data,
+ and this is what you must save (not the pcre[16]_extra block itself).
+ The length of the study data can be obtained by calling
+ pcre[16]_fullinfo() with an argument of PCRE_INFO_STUDYSIZE. Remember
+ to check that pcre[16]_study() did return a non-NULL value before try-
+ ing to save the study data.
RE-USING A PRECOMPILED PATTERN
- Re-using a precompiled pattern is straightforward. Having reloaded it
- into main memory, you pass its pointer to pcre_exec() or
- pcre_dfa_exec() in the usual way. This should work even on another
- host, and even if that host has the opposite endianness to the one
- where the pattern was compiled.
+ Re-using a precompiled pattern is straightforward. Having reloaded it
+ into main memory, called pcre[16]_pattern_to_host_byte_order() if nec-
+ essary, you pass its pointer to pcre[16]_exec() or pcre[16]_dfa_exec()
+ in the usual way.
However, if you passed a pointer to custom character tables when the
- pattern was compiled (the tableptr argument of pcre_compile()), you
- must now pass a similar pointer to pcre_exec() or pcre_dfa_exec(),
- because the value saved with the compiled pattern will obviously be
- nonsense. A field in a pcre_extra() block is used to pass this data, as
- described in the section on matching a pattern in the pcreapi documen-
- tation.
+ pattern was compiled (the tableptr argument of pcre[16]_compile()), you
+ must now pass a similar pointer to pcre[16]_exec() or
+ pcre[16]_dfa_exec(), because the value saved with the compiled pattern
+ will obviously be nonsense. A field in a pcre[16]_extra() block is used
+ to pass this data, as described in the section on matching a pattern in
+ the pcreapi documentation.
If you did not provide custom character tables when the pattern was
- compiled, the pointer in the compiled pattern is NULL, which causes
- pcre_exec() to use PCRE's internal tables. Thus, you do not need to
- take any special action at run time in this case.
+ compiled, the pointer in the compiled pattern is NULL, which causes the
+ matching functions to use PCRE's internal tables. Thus, you do not need
+ to take any special action at run time in this case.
If you saved study data with the compiled pattern, you need to create
- your own pcre_extra data block and set the study_data field to point to
- the reloaded study data. You must also set the PCRE_EXTRA_STUDY_DATA
- bit in the flags field to indicate that study data is present. Then
- pass the pcre_extra block to pcre_exec() or pcre_dfa_exec() in the
- usual way.
+ your own pcre[16]_extra data block and set the study_data field to
+ point to the reloaded study data. You must also set the
+ PCRE_EXTRA_STUDY_DATA bit in the flags field to indicate that study
+ data is present. Then pass the pcre[16]_extra block to the matching
+ function in the usual way. If the pattern was studied for just-in-time
+ optimization, that data cannot be saved, and so is lost by a
+ save/restore cycle.
COMPATIBILITY WITH DIFFERENT PCRE RELEASES
@@ -6606,8 +8044,8 @@
REVISION
- Last updated: 17 November 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 10 January 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
@@ -6627,12 +8065,12 @@
COMPILED PATTERN MEMORY USAGE
- Patterns are compiled by PCRE into a reasonably efficient byte code, so
- that most simple patterns do not use much memory. However, there is one
- case where the memory usage of a compiled pattern can be unexpectedly
- large. If a parenthesized subpattern has a quantifier with a minimum
- greater than 1 and/or a limited maximum, the whole subpattern is
- repeated in the compiled code. For example, the pattern
+ Patterns are compiled by PCRE into a reasonably efficient interpretive
+ code, so that most simple patterns do not use much memory. However,
+ there is one case where the memory usage of a compiled pattern can be
+ unexpectedly large. If a parenthesized subpattern has a quantifier with
+ a minimum greater than 1 and/or a limited maximum, the whole subpattern
+ is repeated in the compiled code. For example, the pattern
(abc|def){2,4}
@@ -6650,64 +8088,66 @@
((ab){1,1000}c){1,3}
- uses 51K bytes when compiled. When PCRE is compiled with its default
- internal pointer size of two bytes, the size limit on a compiled pat-
- tern is 64K, and this is reached with the above pattern if the outer
- repetition is increased from 3 to 4. PCRE can be compiled to use larger
- internal pointers and thus handle larger compiled patterns, but it is
- better to try to rewrite your pattern to use less memory if you can.
+ uses 51K bytes when compiled using the 8-bit library. When PCRE is com-
+ piled with its default internal pointer size of two bytes, the size
+ limit on a compiled pattern is 64K data units, and this is reached with
+ the above pattern if the outer repetition is increased from 3 to 4.
+ PCRE can be compiled to use larger internal pointers and thus handle
+ larger compiled patterns, but it is better to try to rewrite your pat-
+ tern to use less memory if you can.
- One way of reducing the memory usage for such patterns is to make use
+ One way of reducing the memory usage for such patterns is to make use
of PCRE's "subroutine" facility. Re-writing the above pattern as
((ab)(?2){0,999}c)(?1){0,2}
reduces the memory requirements to 18K, and indeed it remains under 20K
- even with the outer repetition increased to 100. However, this pattern
- is not exactly equivalent, because the "subroutine" calls are treated
- as atomic groups into which there can be no backtracking if there is a
- subsequent matching failure. Therefore, PCRE cannot do this kind of
- rewriting automatically. Furthermore, there is a noticeable loss of
- speed when executing the modified pattern. Nevertheless, if the atomic
- grouping is not a problem and the loss of speed is acceptable, this
- kind of rewriting will allow you to process patterns that PCRE cannot
+ even with the outer repetition increased to 100. However, this pattern
+ is not exactly equivalent, because the "subroutine" calls are treated
+ as atomic groups into which there can be no backtracking if there is a
+ subsequent matching failure. Therefore, PCRE cannot do this kind of
+ rewriting automatically. Furthermore, there is a noticeable loss of
+ speed when executing the modified pattern. Nevertheless, if the atomic
+ grouping is not a problem and the loss of speed is acceptable, this
+ kind of rewriting will allow you to process patterns that PCRE cannot
otherwise handle.
STACK USAGE AT RUN TIME
- When pcre_exec() is used for matching, certain kinds of pattern can
- cause it to use large amounts of the process stack. In some environ-
- ments the default process stack is quite small, and if it runs out the
- result is often SIGSEGV. This issue is probably the most frequently
- raised problem with PCRE. Rewriting your pattern can often help. The
- pcrestack documentation discusses this issue in detail.
+ When pcre_exec() or pcre16_exec() is used for matching, certain kinds
+ of pattern can cause it to use large amounts of the process stack. In
+ some environments the default process stack is quite small, and if it
+ runs out the result is often SIGSEGV. This issue is probably the most
+ frequently raised problem with PCRE. Rewriting your pattern can often
+ help. The pcrestack documentation discusses this issue in detail.
PROCESSING TIME
- Certain items in regular expression patterns are processed more effi-
+ Certain items in regular expression patterns are processed more effi-
ciently than others. It is more efficient to use a character class like
- [aeiou] than a set of single-character alternatives such as
- (a|e|i|o|u). In general, the simplest construction that provides the
+ [aeiou] than a set of single-character alternatives such as
+ (a|e|i|o|u). In general, the simplest construction that provides the
required behaviour is usually the most efficient. Jeffrey Friedl's book
- contains a lot of useful general discussion about optimizing regular
- expressions for efficient performance. This document contains a few
+ contains a lot of useful general discussion about optimizing regular
+ expressions for efficient performance. This document contains a few
observations about PCRE.
- Using Unicode character properties (the \p, \P, and \X escapes) is
- slow, because PCRE has to scan a structure that contains data for over
- fifteen thousand characters whenever it needs a character's property.
- If you can find an alternative pattern that does not use character
+ Using Unicode character properties (the \p, \P, and \X escapes) is
+ slow, because PCRE has to scan a structure that contains data for over
+ fifteen thousand characters whenever it needs a character's property.
+ If you can find an alternative pattern that does not use character
properties, it will probably be faster.
- By default, the escape sequences \b, \d, \s, and \w, and the POSIX
- character classes such as [:alpha:] do not use Unicode properties,
+ By default, the escape sequences \b, \d, \s, and \w, and the POSIX
+ character classes such as [:alpha:] do not use Unicode properties,
partly for backwards compatibility, and partly for performance reasons.
- However, you can set PCRE_UCP if you want Unicode character properties
- to be used. This can double the matching time for items such as \d,
- when matched with pcre_exec(); the performance loss is less with
- pcre_dfa_exec(), and in both cases there is not much difference for \b.
+ However, you can set PCRE_UCP if you want Unicode character properties
+ to be used. This can double the matching time for items such as \d,
+ when matched with a traditional matching function; the performance loss
+ is less with a DFA matching function, and in both cases there is not
+ much difference for \b.
When a pattern begins with .* not in parentheses, or in parentheses
that are not the subject of a backreference, and the PCRE_DOTALL option
@@ -6774,8 +8214,8 @@
REVISION
- Last updated: 16 May 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 09 January 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
@@ -6804,51 +8244,52 @@
DESCRIPTION
- This set of functions provides a POSIX-style API to the PCRE regular
- expression package. See the pcreapi documentation for a description of
- PCRE's native API, which contains much additional functionality.
+ This set of functions provides a POSIX-style API for the PCRE regular
+ expression 8-bit library. See the pcreapi documentation for a descrip-
+ tion of PCRE's native API, which contains much additional functional-
+ ity. There is no POSIX-style wrapper for PCRE's 16-bit library.
The functions described here are just wrapper functions that ultimately
call the PCRE native API. Their prototypes are defined in the
- pcreposix.h header file, and on Unix systems the library itself is
- called pcreposix.a, so can be accessed by adding -lpcreposix to the
- command for linking an application that uses them. Because the POSIX
+ pcreposix.h header file, and on Unix systems the library itself is
+ called pcreposix.a, so can be accessed by adding -lpcreposix to the
+ command for linking an application that uses them. Because the POSIX
functions call the native ones, it is also necessary to add -lpcre.
- I have implemented only those POSIX option bits that can be reasonably
- mapped to PCRE native options. In addition, the option REG_EXTENDED is
- defined with the value zero. This has no effect, but since programs
- that are written to the POSIX interface often use it, this makes it
- easier to slot in PCRE as a replacement library. Other POSIX options
+ I have implemented only those POSIX option bits that can be reasonably
+ mapped to PCRE native options. In addition, the option REG_EXTENDED is
+ defined with the value zero. This has no effect, but since programs
+ that are written to the POSIX interface often use it, this makes it
+ easier to slot in PCRE as a replacement library. Other POSIX options
are not even defined.
- There are also some other options that are not defined by POSIX. These
+ There are also some other options that are not defined by POSIX. These
have been added at the request of users who want to make use of certain
PCRE-specific features via the POSIX calling interface.
- When PCRE is called via these functions, it is only the API that is
- POSIX-like in style. The syntax and semantics of the regular expres-
- sions themselves are still those of Perl, subject to the setting of
- various PCRE options, as described below. "POSIX-like in style" means
- that the API approximates to the POSIX definition; it is not fully
- POSIX-compatible, and in multi-byte encoding domains it is probably
+ When PCRE is called via these functions, it is only the API that is
+ POSIX-like in style. The syntax and semantics of the regular expres-
+ sions themselves are still those of Perl, subject to the setting of
+ various PCRE options, as described below. "POSIX-like in style" means
+ that the API approximates to the POSIX definition; it is not fully
+ POSIX-compatible, and in multi-byte encoding domains it is probably
even less compatible.
- The header for these functions is supplied as pcreposix.h to avoid any
- potential clash with other POSIX libraries. It can, of course, be
+ The header for these functions is supplied as pcreposix.h to avoid any
+ potential clash with other POSIX libraries. It can, of course, be
renamed or aliased as regex.h, which is the "correct" name. It provides
- two structure types, regex_t for compiled internal forms, and reg-
- match_t for returning captured substrings. It also defines some con-
- stants whose names start with "REG_"; these are used for setting
+ two structure types, regex_t for compiled internal forms, and reg-
+ match_t for returning captured substrings. It also defines some con-
+ stants whose names start with "REG_"; these are used for setting
options and identifying error codes.
COMPILING A PATTERN
- The function regcomp() is called to compile a pattern into an internal
- form. The pattern is a C string terminated by a binary zero, and is
- passed in the argument pattern. The preg argument is a pointer to a
- regex_t structure that is used as a base for storing information about
+ The function regcomp() is called to compile a pattern into an internal
+ form. The pattern is a C string terminated by a binary zero, and is
+ passed in the argument pattern. The preg argument is a pointer to a
+ regex_t structure that is used as a base for storing information about
the compiled regular expression.
The argument cflags is either zero, or contains one or more of the bits
@@ -6862,58 +8303,58 @@
REG_ICASE
- The PCRE_CASELESS option is set when the regular expression is passed
+ The PCRE_CASELESS option is set when the regular expression is passed
for compilation to the native function.
REG_NEWLINE
- The PCRE_MULTILINE option is set when the regular expression is passed
- for compilation to the native function. Note that this does not mimic
- the defined POSIX behaviour for REG_NEWLINE (see the following sec-
+ The PCRE_MULTILINE option is set when the regular expression is passed
+ for compilation to the native function. Note that this does not mimic
+ the defined POSIX behaviour for REG_NEWLINE (see the following sec-
tion).
REG_NOSUB
- The PCRE_NO_AUTO_CAPTURE option is set when the regular expression is
+ The PCRE_NO_AUTO_CAPTURE option is set when the regular expression is
passed for compilation to the native function. In addition, when a pat-
- tern that is compiled with this flag is passed to regexec() for match-
- ing, the nmatch and pmatch arguments are ignored, and no captured
+ tern that is compiled with this flag is passed to regexec() for match-
+ ing, the nmatch and pmatch arguments are ignored, and no captured
strings are returned.
REG_UCP
- The PCRE_UCP option is set when the regular expression is passed for
- compilation to the native function. This causes PCRE to use Unicode
- properties when matchine \d, \w, etc., instead of just recognizing
+ The PCRE_UCP option is set when the regular expression is passed for
+ compilation to the native function. This causes PCRE to use Unicode
+ properties when matchine \d, \w, etc., instead of just recognizing
ASCII values. Note that REG_UTF8 is not part of the POSIX standard.
REG_UNGREEDY
- The PCRE_UNGREEDY option is set when the regular expression is passed
- for compilation to the native function. Note that REG_UNGREEDY is not
+ The PCRE_UNGREEDY option is set when the regular expression is passed
+ for compilation to the native function. Note that REG_UNGREEDY is not
part of the POSIX standard.
REG_UTF8
- The PCRE_UTF8 option is set when the regular expression is passed for
- compilation to the native function. This causes the pattern itself and
- all data strings used for matching it to be treated as UTF-8 strings.
+ The PCRE_UTF8 option is set when the regular expression is passed for
+ compilation to the native function. This causes the pattern itself and
+ all data strings used for matching it to be treated as UTF-8 strings.
Note that REG_UTF8 is not part of the POSIX standard.
- In the absence of these flags, no options are passed to the native
- function. This means the the regex is compiled with PCRE default
- semantics. In particular, the way it handles newline characters in the
- subject string is the Perl way, not the POSIX way. Note that setting
- PCRE_MULTILINE has only some of the effects specified for REG_NEWLINE.
- It does not affect the way newlines are matched by . (they are not) or
+ In the absence of these flags, no options are passed to the native
+ function. This means the the regex is compiled with PCRE default
+ semantics. In particular, the way it handles newline characters in the
+ subject string is the Perl way, not the POSIX way. Note that setting
+ PCRE_MULTILINE has only some of the effects specified for REG_NEWLINE.
+ It does not affect the way newlines are matched by . (they are not) or
by a negative class such as [^a] (they are).
- The yield of regcomp() is zero on success, and non-zero otherwise. The
+ The yield of regcomp() is zero on success, and non-zero otherwise. The
preg structure is filled in on success, and one member of the structure
- is public: re_nsub contains the number of capturing subpatterns in the
+ is public: re_nsub contains the number of capturing subpatterns in the
regular expression. Various error codes are defined in the header file.
- NOTE: If the yield of regcomp() is non-zero, you must not attempt to
+ NOTE: If the yield of regcomp() is non-zero, you must not attempt to
use the contents of the preg structure. If, for example, you pass it to
regexec(), the result is undefined and your program is likely to crash.
@@ -6921,9 +8362,9 @@
MATCHING NEWLINE CHARACTERS
This area is not simple, because POSIX and Perl take different views of
- things. It is not possible to get PCRE to obey POSIX semantics, but
- then PCRE was never intended to be a POSIX engine. The following table
- lists the different possibilities for matching newline characters in
+ things. It is not possible to get PCRE to obey POSIX semantics, but
+ then PCRE was never intended to be a POSIX engine. The following table
+ lists the different possibilities for matching newline characters in
PCRE:
Default Change with
@@ -6945,19 +8386,19 @@
^ matches \n in middle no REG_NEWLINE
PCRE's behaviour is the same as Perl's, except that there is no equiva-
- lent for PCRE_DOLLAR_ENDONLY in Perl. In both PCRE and Perl, there is
+ lent for PCRE_DOLLAR_ENDONLY in Perl. In both PCRE and Perl, there is
no way to stop newline from matching [^a].
- The default POSIX newline handling can be obtained by setting
- PCRE_DOTALL and PCRE_DOLLAR_ENDONLY, but there is no way to make PCRE
+ The default POSIX newline handling can be obtained by setting
+ PCRE_DOTALL and PCRE_DOLLAR_ENDONLY, but there is no way to make PCRE
behave exactly as for the REG_NEWLINE action.
MATCHING A PATTERN
- The function regexec() is called to match a compiled pattern preg
- against a given string, which is by default terminated by a zero byte
- (but see REG_STARTEND below), subject to the options in eflags. These
+ The function regexec() is called to match a compiled pattern preg
+ against a given string, which is by default terminated by a zero byte
+ (but see REG_STARTEND below), subject to the options in eflags. These
can be:
REG_NOTBOL
@@ -6979,17 +8420,17 @@
REG_STARTEND
- The string is considered to start at string + pmatch[0].rm_so and to
- have a terminating NUL located at string + pmatch[0].rm_eo (there need
- not actually be a NUL at that location), regardless of the value of
- nmatch. This is a BSD extension, compatible with but not specified by
- IEEE Standard 1003.2 (POSIX.2), and should be used with caution in
+ The string is considered to start at string + pmatch[0].rm_so and to
+ have a terminating NUL located at string + pmatch[0].rm_eo (there need
+ not actually be a NUL at that location), regardless of the value of
+ nmatch. This is a BSD extension, compatible with but not specified by
+ IEEE Standard 1003.2 (POSIX.2), and should be used with caution in
software intended to be portable to other systems. Note that a non-zero
rm_so does not imply REG_NOTBOL; REG_STARTEND affects only the location
of the string, not how it is matched.
- If the pattern was compiled with the REG_NOSUB flag, no data about any
- matched strings is returned. The nmatch and pmatch arguments of
+ If the pattern was compiled with the REG_NOSUB flag, no data about any
+ matched strings is returned. The nmatch and pmatch arguments of
regexec() are ignored.
If the value of nmatch is zero, or if the value pmatch is NULL, no data
@@ -6997,34 +8438,34 @@
Otherwise,the portion of the string that was matched, and also any cap-
tured substrings, are returned via the pmatch argument, which points to
- an array of nmatch structures of type regmatch_t, containing the mem-
- bers rm_so and rm_eo. These contain the offset to the first character
- of each substring and the offset to the first character after the end
- of each substring, respectively. The 0th element of the vector relates
- to the entire portion of string that was matched; subsequent elements
- relate to the capturing subpatterns of the regular expression. Unused
+ an array of nmatch structures of type regmatch_t, containing the mem-
+ bers rm_so and rm_eo. These contain the offset to the first character
+ of each substring and the offset to the first character after the end
+ of each substring, respectively. The 0th element of the vector relates
+ to the entire portion of string that was matched; subsequent elements
+ relate to the capturing subpatterns of the regular expression. Unused
entries in the array have both structure members set to -1.
- A successful match yields a zero return; various error codes are
- defined in the header file, of which REG_NOMATCH is the "expected"
+ A successful match yields a zero return; various error codes are
+ defined in the header file, of which REG_NOMATCH is the "expected"
failure code.
ERROR MESSAGES
The regerror() function maps a non-zero errorcode from either regcomp()
- or regexec() to a printable message. If preg is not NULL, the error
+ or regexec() to a printable message. If preg is not NULL, the error
should have arisen from the use of that structure. A message terminated
- by a binary zero is placed in errbuf. The length of the message,
- including the zero, is limited to errbuf_size. The yield of the func-
+ by a binary zero is placed in errbuf. The length of the message,
+ including the zero, is limited to errbuf_size. The yield of the func-
tion is the size of buffer needed to hold the whole message.
MEMORY USAGE
- Compiling a regular expression causes memory to be allocated and asso-
- ciated with the preg structure. The function regfree() frees all such
- memory, after which preg may no longer be used as a compiled expres-
+ Compiling a regular expression causes memory to be allocated and asso-
+ ciated with the preg structure. The function regfree() frees all such
+ memory, after which preg may no longer be used as a compiled expres-
sion.
@@ -7037,8 +8478,8 @@
REVISION
- Last updated: 16 May 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 09 January 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
@@ -7059,13 +8500,14 @@
The C++ wrapper for PCRE was provided by Google Inc. Some additional
functionality was added by Giuseppe Maxia. This brief man page was con-
structed from the notes in the pcrecpp.h file, which should be con-
- sulted for further details.
+ sulted for further details. Note that the C++ wrapper supports only the
+ original 8-bit PCRE library. There is no 16-bit support at present.
MATCHING INTERFACE
- The "FullMatch" operation checks that supplied text matches a supplied
- pattern exactly. If pointer arguments are supplied, it copies matched
+ The "FullMatch" operation checks that supplied text matches a supplied
+ pattern exactly. If pointer arguments are supplied, it copies matched
sub-strings that match sub-patterns into them.
Example: successful match
@@ -7079,10 +8521,10 @@
Example: creating a temporary RE object:
pcrecpp::RE("h.*o").FullMatch("hello");
- You can pass in a "const char*" or a "string" for "text". The examples
- below tend to use a const char*. You can, as in the different examples
- above, store the RE object explicitly in a variable or use a temporary
- RE object. The examples below use one mode or the other arbitrarily.
+ You can pass in a "const char*" or a "string" for "text". The examples
+ below tend to use a const char*. You can, as in the different examples
+ above, store the RE object explicitly in a variable or use a temporary
+ RE object. The examples below use one mode or the other arbitrarily.
Either could correctly be used for any of these examples.
You must supply extra pointer arguments to extract matched subpieces.
@@ -7108,7 +8550,7 @@
Example: fails because string cannot be stored in integer
!pcrecpp::RE("(.*)").FullMatch("ruby", &i);
- The provided pointer arguments can be pointers to any scalar numeric
+ The provided pointer arguments can be pointers to any scalar numeric
type, or one of:
string (matched piece is copied to string)
@@ -7116,7 +8558,7 @@
T (where "bool T::ParseFrom(const char*, int)" exists)
NULL (the corresponding matched sub-pattern is not copied)
- The function returns true iff all of the following conditions are sat-
+ The function returns true iff all of the following conditions are sat-
isfied:
a. "text" matches "pattern" exactly;
@@ -7131,41 +8573,41 @@
number of sub-patterns, "i"th captured sub-pattern is
ignored.
- CAVEAT: An optional sub-pattern that does not exist in the matched
- string is assigned the empty string. Therefore, the following will
+ CAVEAT: An optional sub-pattern that does not exist in the matched
+ string is assigned the empty string. Therefore, the following will
return false (because the empty string is not a valid number):
int number;
pcrecpp::RE::FullMatch("abc", "[a-z]+(\\d+)?", &number);
- The matching interface supports at most 16 arguments per call. If you
- need more, consider using the more general interface
+ The matching interface supports at most 16 arguments per call. If you
+ need more, consider using the more general interface
pcrecpp::RE::DoMatch. See pcrecpp.h for the signature for DoMatch.
- NOTE: Do not use no_arg, which is used internally to mark the end of a
- list of optional arguments, as a placeholder for missing arguments, as
+ NOTE: Do not use no_arg, which is used internally to mark the end of a
+ list of optional arguments, as a placeholder for missing arguments, as
this can lead to segfaults.
QUOTING METACHARACTERS
- You can use the "QuoteMeta" operation to insert backslashes before all
- potentially meaningful characters in a string. The returned string,
+ You can use the "QuoteMeta" operation to insert backslashes before all
+ potentially meaningful characters in a string. The returned string,
used as a regular expression, will exactly match the original string.
Example:
string quoted = RE::QuoteMeta(unquoted);
- Note that it's legal to escape a character even if it has no special
- meaning in a regular expression -- so this function does that. (This
- also makes it identical to the perl function of the same name; see
- "perldoc -f quotemeta".) For example, "1.5-2.0?" becomes
+ Note that it's legal to escape a character even if it has no special
+ meaning in a regular expression -- so this function does that. (This
+ also makes it identical to the perl function of the same name; see
+ "perldoc -f quotemeta".) For example, "1.5-2.0?" becomes
"1\.5\-2\.0\?".
PARTIAL MATCHES
- You can use the "PartialMatch" operation when you want the pattern to
+ You can use the "PartialMatch" operation when you want the pattern to
match any substring of the text.
Example: simple search for a string:
@@ -7180,13 +8622,13 @@
UTF-8 AND THE MATCHING INTERFACE
- By default, pattern and text are plain text, one byte per character.
- The UTF8 flag, passed to the constructor, causes both pattern and
+ By default, pattern and text are plain text, one byte per character.
+ The UTF8 flag, passed to the constructor, causes both pattern and
string to be treated as UTF-8 text, still a byte stream but potentially
- multiple bytes per character. In practice, the text is likelier to be
- UTF-8 than the pattern, but the match returned may depend on the UTF8
- flag, so always use it when matching UTF8 text. For example, "." will
- match one byte normally but with UTF8 set may match up to three bytes
+ multiple bytes per character. In practice, the text is likelier to be
+ UTF-8 than the pattern, but the match returned may depend on the UTF8
+ flag, so always use it when matching UTF8 text. For example, "." will
+ match one byte normally but with UTF8 set may match up to three bytes
of a multi-byte character.
Example:
@@ -7205,9 +8647,9 @@
PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE
- PCRE defines some modifiers to change the behavior of the regular
- expression engine. The C++ wrapper defines an auxiliary class,
- RE_Options, as a vehicle to pass such modifiers to a RE class. Cur-
+ PCRE defines some modifiers to change the behavior of the regular
+ expression engine. The C++ wrapper defines an auxiliary class,
+ RE_Options, as a vehicle to pass such modifiers to a RE class. Cur-
rently, the following modifiers are supported:
modifier description Perl corresponding
@@ -7217,20 +8659,20 @@
PCRE_DOTALL dot matches newlines /s
PCRE_DOLLAR_ENDONLY $ matches only at end N/A
PCRE_EXTRA strict escape parsing N/A
- PCRE_EXTENDED ignore whitespaces /x
+ PCRE_EXTENDED ignore white spaces /x
PCRE_UTF8 handles UTF8 chars built-in
PCRE_UNGREEDY reverses * and *? N/A
PCRE_NO_AUTO_CAPTURE disables capturing parens N/A (*)
- (*) Both Perl and PCRE allow non capturing parentheses by means of the
- "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not cap-
+ (*) Both Perl and PCRE allow non capturing parentheses by means of the
+ "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not cap-
ture, while (ab|cd) does.
- For a full account on how each modifier works, please check the PCRE
+ For a full account on how each modifier works, please check the PCRE
API reference page.
- For each modifier, there are two member functions whose name is made
- out of the modifier in lowercase, without the "PCRE_" prefix. For
+ For each modifier, there are two member functions whose name is made
+ out of the modifier in lowercase, without the "PCRE_" prefix. For
instance, PCRE_CASELESS is handled by
bool caseless()
@@ -7240,28 +8682,28 @@
RE_Options & set_caseless(bool)
which sets or unsets the modifier. Moreover, PCRE_EXTRA_MATCH_LIMIT can
- be accessed through the set_match_limit() and match_limit() member
- functions. Setting match_limit to a non-zero value will limit the exe-
- cution of pcre to keep it from doing bad things like blowing the stack
- or taking an eternity to return a result. A value of 5000 is good
- enough to stop stack blowup in a 2MB thread stack. Setting match_limit
- to zero disables match limiting. Alternatively, you can call
- match_limit_recursion() which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to
- limit how much PCRE recurses. match_limit() limits the number of
+ be accessed through the set_match_limit() and match_limit() member
+ functions. Setting match_limit to a non-zero value will limit the exe-
+ cution of pcre to keep it from doing bad things like blowing the stack
+ or taking an eternity to return a result. A value of 5000 is good
+ enough to stop stack blowup in a 2MB thread stack. Setting match_limit
+ to zero disables match limiting. Alternatively, you can call
+ match_limit_recursion() which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to
+ limit how much PCRE recurses. match_limit() limits the number of
matches PCRE does; match_limit_recursion() limits the depth of internal
recursion, and therefore the amount of stack that is used.
- Normally, to pass one or more modifiers to a RE class, you declare a
+ Normally, to pass one or more modifiers to a RE class, you declare a
RE_Options object, set the appropriate options, and pass this object to
a RE constructor. Example:
- RE_options opt;
+ RE_Options opt;
opt.set_caseless(true);
if (RE("HELLO", opt).PartialMatch("hello world")) ...
RE_options has two constructors. The default constructor takes no argu-
- ments and creates a set of flags that are off by default. The optional
- parameter option_flags is to facilitate transfer of legacy code from C
+ ments and creates a set of flags that are off by default. The optional
+ parameter option_flags is to facilitate transfer of legacy code from C
programs. This lets you do
RE(pattern,
@@ -7275,15 +8717,15 @@
If you are going to pass one of the most used modifiers, there are some
convenience functions that return a RE_Options class with the appropri-
- ate modifier already set: CASELESS(), UTF8(), MULTILINE(), DOTALL(),
+ ate modifier already set: CASELESS(), UTF8(), MULTILINE(), DOTALL(),
and EXTENDED().
- If you need to set several options at once, and you don't want to go
- through the pains of declaring a RE_Options object and setting several
- options, there is a parallel method that give you such ability on the
- fly. You can concatenate several set_xxxxx() member functions, since
- each of them returns a reference to its class object. For example, to
- pass PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one
+ If you need to set several options at once, and you don't want to go
+ through the pains of declaring a RE_Options object and setting several
+ options, there is a parallel method that give you such ability on the
+ fly. You can concatenate several set_xxxxx() member functions, since
+ each of them returns a reference to its class object. For example, to
+ pass PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one
statement, you may write:
RE(" ^ xyz \\s+ .* blah$",
@@ -7295,10 +8737,10 @@
SCANNING TEXT INCREMENTALLY
- The "Consume" operation may be useful if you want to repeatedly match
+ The "Consume" operation may be useful if you want to repeatedly match
regular expressions at the front of a string and skip over them as they
- match. This requires use of the "StringPiece" type, which represents a
- sub-range of a real string. Like RE, StringPiece is defined in the
+ match. This requires use of the "StringPiece" type, which represents a
+ sub-range of a real string. Like RE, StringPiece is defined in the
pcrecpp namespace.
Example: read lines of the form "var = value" from a string.
@@ -7312,11 +8754,11 @@
...;
}
- Each successful call to "Consume" will set "var/value", and also
+ Each successful call to "Consume" will set "var/value", and also
advance "input" so it points past the matched text.
- The "FindAndConsume" operation is similar to "Consume" but does not
- anchor your match at the beginning of the string. For example, you
+ The "FindAndConsume" operation is similar to "Consume" but does not
+ anchor your match at the beginning of the string. For example, you
could extract all words from a string by repeatedly calling
pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word)
@@ -7325,10 +8767,10 @@
PARSING HEX/OCTAL/C-RADIX NUMBERS
By default, if you pass a pointer to a numeric value, the corresponding
- text is interpreted as a base-10 number. You can instead wrap the
+ text is interpreted as a base-10 number. You can instead wrap the
pointer with a call to one of the operators Hex(), Octal(), or CRadix()
- to interpret the text in another base. The CRadix operator interprets
- C-style "0" (base-8) and "0x" (base-16) prefixes, but defaults to
+ to interpret the text in another base. The CRadix operator interprets
+ C-style "0" (base-8) and "0x" (base-16) prefixes, but defaults to
base-10.
Example:
@@ -7343,30 +8785,30 @@
REPLACING PARTS OF STRINGS
- You can replace the first match of "pattern" in "str" with "rewrite".
- Within "rewrite", backslash-escaped digits (\1 to \9) can be used to
- insert text matching corresponding parenthesized group from the pat-
+ You can replace the first match of "pattern" in "str" with "rewrite".
+ Within "rewrite", backslash-escaped digits (\1 to \9) can be used to
+ insert text matching corresponding parenthesized group from the pat-
tern. \0 in "rewrite" refers to the entire matching text. For example:
string s = "yabba dabba doo";
pcrecpp::RE("b+").Replace("d", &s);
- will leave "s" containing "yada dabba doo". The result is true if the
+ will leave "s" containing "yada dabba doo". The result is true if the
pattern matches and a replacement occurs, false otherwise.
- GlobalReplace is like Replace except that it replaces all occurrences
- of the pattern in the string with the rewrite. Replacements are not
+ GlobalReplace is like Replace except that it replaces all occurrences
+ of the pattern in the string with the rewrite. Replacements are not
subject to re-matching. For example:
string s = "yabba dabba doo";
pcrecpp::RE("b+").GlobalReplace("d", &s);
- will leave "s" containing "yada dada doo". It returns the number of
+ will leave "s" containing "yada dada doo". It returns the number of
replacements made.
- Extract is like Replace, except that if the pattern matches, "rewrite"
- is copied into "out" (an additional argument) with substitutions. The
- non-matching portions of "text" are ignored. Returns true iff a match
+ Extract is like Replace, except that if the pattern matches, "rewrite"
+ is copied into "out" (an additional argument) with substitutions. The
+ non-matching portions of "text" are ignored. Returns true iff a match
occurred and the extraction happened successfully; if no match occurs,
the string is left unaffected.
@@ -7379,7 +8821,7 @@
REVISION
- Last updated: 17 March 2009
+ Last updated: 08 January 2012
------------------------------------------------------------------------------
@@ -7398,57 +8840,58 @@
do not have a copy of the PCRE distribution, you can save this listing
to re-create pcredemo.c.
- The program compiles the regular expression that is its first argument,
- and matches it against the subject string in its second argument. No
- PCRE options are set, and default character tables are used. If match-
- ing succeeds, the program outputs the portion of the subject that
- matched, together with the contents of any captured substrings.
+ The demonstration program, which uses the original PCRE 8-bit library,
+ compiles the regular expression that is its first argument, and matches
+ it against the subject string in its second argument. No PCRE options
+ are set, and default character tables are used. If matching succeeds,
+ the program outputs the portion of the subject that matched, together
+ with the contents of any captured substrings.
If the -g option is given on the command line, the program then goes on
to check for further matches of the same regular expression in the same
- subject string. The logic is a little bit tricky because of the possi-
- bility of matching an empty string. Comments in the code explain what
+ subject string. The logic is a little bit tricky because of the possi-
+ bility of matching an empty string. Comments in the code explain what
is going on.
- If PCRE is installed in the standard include and library directories
+ If PCRE is installed in the standard include and library directories
for your operating system, you should be able to compile the demonstra-
tion program using this command:
gcc -o pcredemo pcredemo.c -lpcre
- If PCRE is installed elsewhere, you may need to add additional options
- to the command line. For example, on a Unix-like system that has PCRE
- installed in /usr/local, you can compile the demonstration program
+ If PCRE is installed elsewhere, you may need to add additional options
+ to the command line. For example, on a Unix-like system that has PCRE
+ installed in /usr/local, you can compile the demonstration program
using a command like this:
gcc -o pcredemo -I/usr/local/include pcredemo.c \
-L/usr/local/lib -lpcre
- In a Windows environment, if you want to statically link the program
+ In a Windows environment, if you want to statically link the program
against a non-dll pcre.a file, you must uncomment the line that defines
- PCRE_STATIC before including pcre.h, because otherwise the pcre_mal-
+ PCRE_STATIC before including pcre.h, because otherwise the pcre_mal-
loc() and pcre_free() exported functions will be declared
__declspec(dllimport), with unwanted results.
- Once you have compiled and linked the demonstration program, you can
+ Once you have compiled and linked the demonstration program, you can
run simple tests like this:
./pcredemo 'cat|dog' 'the cat sat on the mat'
./pcredemo -g 'cat|dog' 'the dog sat on the cat'
- Note that there is a much more comprehensive test program, called
- pcretest, which supports many more facilities for testing regular
- expressions and the PCRE library. The pcredemo program is provided as a
- simple coding example.
+ Note that there is a much more comprehensive test program, called
+ pcretest, which supports many more facilities for testing regular
+ expressions and both PCRE libraries. The pcredemo program is provided
+ as a simple coding example.
- If you try to run pcredemo when PCRE is not installed in the standard
- library directory, you may get an error like this on some operating
+ If you try to run pcredemo when PCRE is not installed in the standard
+ library directory, you may get an error like this on some operating
systems (e.g. Solaris):
- ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or
+ ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or
directory
- This is caused by the way shared library support works on those sys-
+ This is caused by the way shared library support works on those sys-
tems. You need to add
-R/usr/local/lib
@@ -7465,9 +8908,71 @@
REVISION
- Last updated: 17 November 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 10 January 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
+PCRELIMITS(3) PCRELIMITS(3)
+
+
+NAME
+ PCRE - Perl-compatible regular expressions
+
+
+SIZE AND OTHER LIMITATIONS
+
+ There are some size limitations in PCRE but it is hoped that they will
+ never in practice be relevant.
+
+ The maximum length of a compiled pattern is approximately 64K data
+ units (bytes for the 8-bit library, 16-bit units for the 16-bit
+ library) if PCRE is compiled with the default internal linkage size of
+ 2 bytes. If you want to process regular expressions that are truly
+ enormous, you can compile PCRE with an internal linkage size of 3 or 4
+ (when building the 16-bit library, 3 is rounded up to 4). See the
+ README file in the source distribution and the pcrebuild documentation
+ for details. In these cases the limit is substantially larger. How-
+ ever, the speed of execution is slower.
+
+ All values in repeating quantifiers must be less than 65536.
+
+ There is no limit to the number of parenthesized subpatterns, but there
+ can be no more than 65535 capturing subpatterns.
+
+ There is a limit to the number of forward references to subsequent sub-
+ patterns of around 200,000. Repeated forward references with fixed
+ upper limits, for example, (?2){0,100} when subpattern number 2 is to
+ the right, are included in the count. There is no limit to the number
+ of backward references.
+
+ The maximum length of name for a named subpattern is 32 characters, and
+ the maximum number of named subpatterns is 10000.
+
+ The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or
+ (*THEN) verb is 255 for the 8-bit library and 65535 for the 16-bit
+ library.
+
+ The maximum length of a subject string is the largest positive number
+ that an integer variable can hold. However, when using the traditional
+ matching function, PCRE uses recursion to handle subpatterns and indef-
+ inite repetition. This means that the available stack space may limit
+ the size of a subject string that can be processed by certain patterns.
+ For a discussion of stack issues, see the pcrestack documentation.
+
+
+AUTHOR
+
+ Philip Hazel
+ University Computing Service
+ Cambridge CB2 3QH, England.
+
+
+REVISION
+
+ Last updated: 04 May 2012
+ Copyright (c) 1997-2012 University of Cambridge.
+------------------------------------------------------------------------------
+
+
PCRESTACK(3) PCRESTACK(3)
@@ -7477,12 +8982,14 @@
PCRE DISCUSSION OF STACK USAGE
- When you call pcre_exec(), it makes use of an internal function called
- match(). This calls itself recursively at branch points in the pattern,
- in order to remember the state of the match so that it can back up and
- try a different alternative if the first one fails. As matching pro-
- ceeds deeper and deeper into the tree of possibilities, the recursion
- depth increases.
+ When you call pcre[16]_exec(), it makes use of an internal function
+ called match(). This calls itself recursively at branch points in the
+ pattern, in order to remember the state of the match so that it can
+ back up and try a different alternative if the first one fails. As
+ matching proceeds deeper and deeper into the tree of possibilities, the
+ recursion depth increases. The match() function is also called in other
+ circumstances, for example, whenever a parenthesized sub-pattern is
+ entered, and in certain cases of repetition.
Not all calls of match() increase the recursion depth; for an item such
as a* it may be called several times at the same level, after matching
@@ -7491,20 +8998,28 @@
result of the current call (a "tail recursion"), the function is just
restarted instead.
- The pcre_dfa_exec() function operates in an entirely different way, and
- uses recursion only when there is a regular expression recursion or
+ The above comments apply when pcre[16]_exec() is run in its normal
+ interpretive manner. If the pattern was studied with the
+ PCRE_STUDY_JIT_COMPILE option, and just-in-time compiling was success-
+ ful, and the options passed to pcre[16]_exec() were not incompatible,
+ the matching process uses the JIT-compiled code instead of the match()
+ function. In this case, the memory requirements are handled entirely
+ differently. See the pcrejit documentation for details.
+
+ The pcre[16]_dfa_exec() function operates in an entirely different way,
+ and uses recursion only when there is a regular expression recursion or
subroutine call in the pattern. This includes the processing of asser-
tion and "once-only" subpatterns, which are handled like subroutine
calls. Normally, these are never very deep, and the limit on the com-
- plexity of pcre_dfa_exec() is controlled by the amount of workspace it
- is given. However, it is possible to write patterns with runaway infi-
- nite recursions; such patterns will cause pcre_dfa_exec() to run out of
- stack. At present, there is no protection against this.
+ plexity of pcre[16]_dfa_exec() is controlled by the amount of workspace
+ it is given. However, it is possible to write patterns with runaway
+ infinite recursions; such patterns will cause pcre[16]_dfa_exec() to
+ run out of stack. At present, there is no protection against this.
- The comments that follow do NOT apply to pcre_dfa_exec(); they are rel-
- evant only for pcre_exec().
+ The comments that follow do NOT apply to pcre[16]_dfa_exec(); they are
+ relevant only for pcre[16]_exec() without the JIT optimization.
- Reducing pcre_exec()'s stack usage
+ Reducing pcre[16]_exec()'s stack usage
Each time that match() is actually called recursively, it uses memory
from the process stack. For certain kinds of pattern and data, very
@@ -7537,31 +9052,31 @@
ing long subject strings is to write repeated parenthesized subpatterns
to match more than one character whenever possible.
- Compiling PCRE to use heap instead of stack for pcre_exec()
+ Compiling PCRE to use heap instead of stack for pcre[16]_exec()
In environments where stack memory is constrained, you might want to
compile PCRE to use heap memory instead of stack for remembering back-
- up points when pcre_exec() is running. This makes it run a lot more
+ up points when pcre[16]_exec() is running. This makes it run a lot more
slowly, however. Details of how to do this are given in the pcrebuild
documentation. When built in this way, instead of using the stack, PCRE
obtains and frees memory by calling the functions that are pointed to
- by the pcre_stack_malloc and pcre_stack_free variables. By default,
- these point to malloc() and free(), but you can replace the pointers to
- cause PCRE to use your own functions. Since the block sizes are always
- the same, and are always freed in reverse order, it may be possible to
- implement customized memory handlers that are more efficient than the
- standard functions.
+ by the pcre[16]_stack_malloc and pcre[16]_stack_free variables. By
+ default, these point to malloc() and free(), but you can replace the
+ pointers to cause PCRE to use your own functions. Since the block sizes
+ are always the same, and are always freed in reverse order, it may be
+ possible to implement customized memory handlers that are more effi-
+ cient than the standard functions.
- Limiting pcre_exec()'s stack usage
+ Limiting pcre[16]_exec()'s stack usage
You can set limits on the number of times that match() is called, both
- in total and recursively. If a limit is exceeded, pcre_exec() returns
- an error code. Setting suitable limits should prevent it from running
- out of stack. The default values of the limits are very large, and
- unlikely ever to operate. They can be changed when PCRE is built, and
- they can also be set when pcre_exec() is called. For details of these
- interfaces, see the pcrebuild documentation and the section on extra
- data for pcre_exec() in the pcreapi documentation.
+ in total and recursively. If a limit is exceeded, pcre[16]_exec()
+ returns an error code. Setting suitable limits should prevent it from
+ running out of stack. The default values of the limits are very large,
+ and unlikely ever to operate. They can be changed when PCRE is built,
+ and they can also be set when pcre[16]_exec() is called. For details of
+ these interfaces, see the pcrebuild documentation and the section on
+ extra data for pcre[16]_exec() in the pcreapi documentation.
As a very rough rule of thumb, you should reckon on about 500 bytes per
recursion. Thus, if you want to limit your stack usage to 8Mb, you
@@ -7572,9 +9087,33 @@
option (-S) that can be used to increase the size of its stack. As long
as the stack is large enough, another option (-M) can be used to find
the smallest limits that allow a particular pattern to match a given
- subject string. This is done by calling pcre_exec() repeatedly with
+ subject string. This is done by calling pcre[16]_exec() repeatedly with
different limits.
+ Obtaining an estimate of stack usage
+
+ The actual amount of stack used per recursion can vary quite a lot,
+ depending on the compiler that was used to build PCRE and the optimiza-
+ tion or debugging options that were set for it. The rule of thumb value
+ of 500 bytes mentioned above may be larger or smaller than what is
+ actually needed. A better approximation can be obtained by running this
+ command:
+
+ pcretest -m -C
+
+ The -C option causes pcretest to output information about the options
+ with which PCRE was compiled. When -m is also given (before -C), infor-
+ mation about stack use is given in a line like this:
+
+ Match recursion uses stack: approximate frame size = 640 bytes
+
+ The value is approximate because some recursions need a bit more (up to
+ perhaps 16 more bytes).
+
+ If the above command is given when PCRE is compiled to use the heap
+ instead of the stack for recursion, the value that is output is the
+ size of each block that is obtained from the heap.
+
Changing stack size in Unix-like systems
In Unix-like environments, there is not often a problem with the stack
@@ -7595,7 +9134,7 @@
This reads the current limits (soft and hard) using getrlimit(), then
attempts to increase the soft limit to 100Mb using setrlimit(). You
- must do this before calling pcre_exec().
+ must do this before calling pcre[16]_exec().
Changing stack size in Mac OS X
@@ -7614,8 +9153,8 @@
REVISION
- Last updated: 03 January 2010
- Copyright (c) 1997-2010 University of Cambridge.
+ Last updated: 21 January 2012
+ Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
diff -Nru pcre3-8.12/doc/pcre16.3 pcre3-8.31/doc/pcre16.3
--- pcre3-8.12/doc/pcre16.3 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/pcre16.3 2012-06-02 10:55:17.000000000 +0000
@@ -0,0 +1,389 @@
+.TH PCRE 3 "14 April 2012" "PCRE 8.31"
+.SH NAME
+PCRE - Perl-compatible regular expressions
+.sp
+.B #include
+.
+.
+.SH "PCRE 16-BIT API BASIC FUNCTIONS"
+.rs
+.sp
+.SM
+.B pcre16 *pcre16_compile(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP,
+.ti +5n
+.B const char **\fIerrptr\fP, int *\fIerroffset\fP,
+.ti +5n
+.B const unsigned char *\fItableptr\fP);
+.PP
+.B pcre16 *pcre16_compile2(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP,
+.ti +5n
+.B int *\fIerrorcodeptr\fP,
+.ti +5n
+.B const char **\fIerrptr\fP, int *\fIerroffset\fP,
+.ti +5n
+.B const unsigned char *\fItableptr\fP);
+.PP
+.B pcre16_extra *pcre16_study(const pcre16 *\fIcode\fP, int \fIoptions\fP,
+.ti +5n
+.B const char **\fIerrptr\fP);
+.PP
+.B void pcre16_free_study(pcre16_extra *\fIextra\fP);
+.PP
+.B int pcre16_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP,"
+.ti +5n
+.B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP,
+.ti +5n
+.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP);
+.PP
+.B int pcre16_dfa_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP,"
+.ti +5n
+.B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP,
+.ti +5n
+.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP,
+.ti +5n
+.B int *\fIworkspace\fP, int \fIwscount\fP);
+.
+.
+.SH "PCRE 16-BIT API STRING EXTRACTION FUNCTIONS"
+.rs
+.sp
+.B int pcre16_copy_named_substring(const pcre16 *\fIcode\fP,
+.ti +5n
+.B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP,
+.ti +5n
+.B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP,
+.ti +5n
+.B PCRE_UCHAR16 *\fIbuffer\fP, int \fIbuffersize\fP);
+.PP
+.B int pcre16_copy_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP,
+.ti +5n
+.B int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR16 *\fIbuffer\fP,
+.ti +5n
+.B int \fIbuffersize\fP);
+.PP
+.B int pcre16_get_named_substring(const pcre16 *\fIcode\fP,
+.ti +5n
+.B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP,
+.ti +5n
+.B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP,
+.ti +5n
+.B PCRE_SPTR16 *\fIstringptr\fP);
+.PP
+.B int pcre16_get_stringnumber(const pcre16 *\fIcode\fP,
+.ti +5n
+.B PCRE_SPTR16 \fIname\fP);
+.PP
+.B int pcre16_get_stringtable_entries(const pcre16 *\fIcode\fP,
+.ti +5n
+.B PCRE_SPTR16 \fIname\fP, PCRE_UCHAR16 **\fIfirst\fP, PCRE_UCHAR16 **\fIlast\fP);
+.PP
+.B int pcre16_get_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP,
+.ti +5n
+.B int \fIstringcount\fP, int \fIstringnumber\fP,
+.ti +5n
+.B PCRE_SPTR16 *\fIstringptr\fP);
+.PP
+.B int pcre16_get_substring_list(PCRE_SPTR16 \fIsubject\fP,
+.ti +5n
+.B int *\fIovector\fP, int \fIstringcount\fP, "PCRE_SPTR16 **\fIlistptr\fP);"
+.PP
+.B void pcre16_free_substring(PCRE_SPTR16 \fIstringptr\fP);
+.PP
+.B void pcre16_free_substring_list(PCRE_SPTR16 *\fIstringptr\fP);
+.
+.
+.SH "PCRE 16-BIT API AUXILIARY FUNCTIONS"
+.rs
+.sp
+.B pcre16_jit_stack *pcre16_jit_stack_alloc(int \fIstartsize\fP, int \fImaxsize\fP);
+.PP
+.B void pcre16_jit_stack_free(pcre16_jit_stack *\fIstack\fP);
+.PP
+.B void pcre16_assign_jit_stack(pcre16_extra *\fIextra\fP,
+.ti +5n
+.B pcre16_jit_callback \fIcallback\fP, void *\fIdata\fP);
+.PP
+.B const unsigned char *pcre16_maketables(void);
+.PP
+.B int pcre16_fullinfo(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP,"
+.ti +5n
+.B int \fIwhat\fP, void *\fIwhere\fP);
+.PP
+.B int pcre16_refcount(pcre16 *\fIcode\fP, int \fIadjust\fP);
+.PP
+.B int pcre16_config(int \fIwhat\fP, void *\fIwhere\fP);
+.PP
+.B const char *pcre16_version(void);
+.PP
+.B int pcre16_pattern_to_host_byte_order(pcre16 *\fIcode\fP,
+.ti +5n
+.B pcre16_extra *\fIextra\fP, const unsigned char *\fItables\fP);
+.
+.
+.SH "PCRE 16-BIT API INDIRECTED FUNCTIONS"
+.rs
+.sp
+.B void *(*pcre16_malloc)(size_t);
+.PP
+.B void (*pcre16_free)(void *);
+.PP
+.B void *(*pcre16_stack_malloc)(size_t);
+.PP
+.B void (*pcre16_stack_free)(void *);
+.PP
+.B int (*pcre16_callout)(pcre16_callout_block *);
+.
+.
+.SH "PCRE 16-BIT API 16-BIT-ONLY FUNCTION"
+.rs
+.sp
+.B int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *\fIoutput\fP,
+.ti +5n
+.B PCRE_SPTR16 \fIinput\fP, int \fIlength\fP, int *\fIbyte_order\fP,
+.ti +5n
+.B int \fIkeep_boms\fP);
+.
+.
+.SH "THE PCRE 16-BIT LIBRARY"
+.rs
+.sp
+Starting with release 8.30, it is possible to compile a PCRE library that
+supports 16-bit character strings, including UTF-16 strings, as well as or
+instead of the original 8-bit library. The majority of the work to make this
+possible was done by Zoltan Herczeg. The two libraries contain identical sets
+of functions, used in exactly the same way. Only the names of the functions and
+the data types of their arguments and results are different. To avoid
+over-complication and reduce the documentation maintenance load, most of the
+PCRE documentation describes the 8-bit library, with only occasional references
+to the 16-bit library. This page describes what is different when you use the
+16-bit library.
+.P
+WARNING: A single application can be linked with both libraries, but you must
+take care when processing any particular pattern to use functions from just one
+library. For example, if you want to study a pattern that was compiled with
+\fBpcre16_compile()\fP, you must do so with \fBpcre16_study()\fP, not
+\fBpcre_study()\fP, and you must free the study data with
+\fBpcre16_free_study()\fP.
+.
+.
+.SH "THE HEADER FILE"
+.rs
+.sp
+There is only one header file, \fBpcre.h\fP. It contains prototypes for all the
+functions in both libraries, as well as definitions of flags, structures, error
+codes, etc.
+.
+.
+.SH "THE LIBRARY NAME"
+.rs
+.sp
+In Unix-like systems, the 16-bit library is called \fBlibpcre16\fP, and can
+normally be accesss by adding \fB-lpcre16\fP to the command for linking an
+application that uses PCRE.
+.
+.
+.SH "STRING TYPES"
+.rs
+.sp
+In the 8-bit library, strings are passed to PCRE library functions as vectors
+of bytes with the C type "char *". In the 16-bit library, strings are passed as
+vectors of unsigned 16-bit quantities. The macro PCRE_UCHAR16 specifies an
+appropriate data type, and PCRE_SPTR16 is defined as "const PCRE_UCHAR16 *". In
+very many environments, "short int" is a 16-bit data type. When PCRE is built,
+it defines PCRE_UCHAR16 as "short int", but checks that it really is a 16-bit
+data type. If it is not, the build fails with an error message telling the
+maintainer to modify the definition appropriately.
+.
+.
+.SH "STRUCTURE TYPES"
+.rs
+.sp
+The types of the opaque structures that are used for compiled 16-bit patterns
+and JIT stacks are \fBpcre16\fP and \fBpcre16_jit_stack\fP respectively. The
+type of the user-accessible structure that is returned by \fBpcre16_study()\fP
+is \fBpcre16_extra\fP, and the type of the structure that is used for passing
+data to a callout function is \fBpcre16_callout_block\fP. These structures
+contain the same fields, with the same names, as their 8-bit counterparts. The
+only difference is that pointers to character strings are 16-bit instead of
+8-bit types.
+.
+.
+.SH "16-BIT FUNCTIONS"
+.rs
+.sp
+For every function in the 8-bit library there is a corresponding function in
+the 16-bit library with a name that starts with \fBpcre16_\fP instead of
+\fBpcre_\fP. The prototypes are listed above. In addition, there is one extra
+function, \fBpcre16_utf16_to_host_byte_order()\fP. This is a utility function
+that converts a UTF-16 character string to host byte order if necessary. The
+other 16-bit functions expect the strings they are passed to be in host byte
+order.
+.P
+The \fIinput\fP and \fIoutput\fP arguments of
+\fBpcre16_utf16_to_host_byte_order()\fP may point to the same address, that is,
+conversion in place is supported. The output buffer must be at least as long as
+the input.
+.P
+The \fIlength\fP argument specifies the number of 16-bit data units in the
+input string; a negative value specifies a zero-terminated string.
+.P
+If \fIbyte_order\fP is NULL, it is assumed that the string starts off in host
+byte order. This may be changed by byte-order marks (BOMs) anywhere in the
+string (commonly as the first character).
+.P
+If \fIbyte_order\fP is not NULL, a non-zero value of the integer to which it
+points means that the input starts off in host byte order, otherwise the
+opposite order is assumed. Again, BOMs in the string can change this. The final
+byte order is passed back at the end of processing.
+.P
+If \fIkeep_boms\fP is not zero, byte-order mark characters (0xfeff) are copied
+into the output string. Otherwise they are discarded.
+.P
+The result of the function is the number of 16-bit units placed into the output
+buffer, including the zero terminator if the string was zero-terminated.
+.
+.
+.SH "SUBJECT STRING OFFSETS"
+.rs
+.sp
+The offsets within subject strings that are returned by the matching functions
+are in 16-bit units rather than bytes.
+.
+.
+.SH "NAMED SUBPATTERNS"
+.rs
+.sp
+The name-to-number translation table that is maintained for named subpatterns
+uses 16-bit characters. The \fBpcre16_get_stringtable_entries()\fP function
+returns the length of each entry in the table as the number of 16-bit data
+units.
+.
+.
+.SH "OPTION NAMES"
+.rs
+.sp
+There are two new general option names, PCRE_UTF16 and PCRE_NO_UTF16_CHECK,
+which correspond to PCRE_UTF8 and PCRE_NO_UTF8_CHECK in the 8-bit library. In
+fact, these new options define the same bits in the options word. There is a
+discussion about the
+.\" HTML
+.\"
+validity of UTF-16 strings
+.\"
+in the
+.\" HREF
+\fBpcreunicode\fP
+.\"
+page.
+.P
+For the \fBpcre16_config()\fP function there is an option PCRE_CONFIG_UTF16
+that returns 1 if UTF-16 support is configured, otherwise 0. If this option is
+given to \fBpcre_config()\fP, or if the PCRE_CONFIG_UTF8 option is given to
+\fBpcre16_config()\fP, the result is the PCRE_ERROR_BADOPTION error.
+.
+.
+.SH "CHARACTER CODES"
+.rs
+.sp
+In 16-bit mode, when PCRE_UTF16 is not set, character values are treated in the
+same way as in 8-bit, non UTF-8 mode, except, of course, that they can range
+from 0 to 0xffff instead of 0 to 0xff. Character types for characters less than
+0xff can therefore be influenced by the locale in the same way as before.
+Characters greater than 0xff have only one case, and no "type" (such as letter
+or digit).
+.P
+In UTF-16 mode, the character code is Unicode, in the range 0 to 0x10ffff, with
+the exception of values in the range 0xd800 to 0xdfff because those are
+"surrogate" values that are used in pairs to encode values greater than 0xffff.
+.P
+A UTF-16 string can indicate its endianness by special code knows as a
+byte-order mark (BOM). The PCRE functions do not handle this, expecting strings
+to be in host byte order. A utility function called
+\fBpcre16_utf16_to_host_byte_order()\fP is provided to help with this (see
+above).
+.
+.
+.SH "ERROR NAMES"
+.rs
+.sp
+The errors PCRE_ERROR_BADUTF16_OFFSET and PCRE_ERROR_SHORTUTF16 correspond to
+their 8-bit counterparts. The error PCRE_ERROR_BADMODE is given when a compiled
+pattern is passed to a function that processes patterns in the other
+mode, for example, if a pattern compiled with \fBpcre_compile()\fP is passed to
+\fBpcre16_exec()\fP.
+.P
+There are new error codes whose names begin with PCRE_UTF16_ERR for invalid
+UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for UTF-8 strings that
+are described in the section entitled
+.\" HTML
+.\"
+"Reason codes for invalid UTF-8 strings"
+.\"
+in the main
+.\" HREF
+\fBpcreapi\fP
+.\"
+page. The UTF-16 errors are:
+.sp
+ PCRE_UTF16_ERR1 Missing low surrogate at end of string
+ PCRE_UTF16_ERR2 Invalid low surrogate follows high surrogate
+ PCRE_UTF16_ERR3 Isolated low surrogate
+ PCRE_UTF16_ERR4 Invalid character 0xfffe
+.
+.
+.SH "ERROR TEXTS"
+.rs
+.sp
+If there is an error while compiling a pattern, the error text that is passed
+back by \fBpcre16_compile()\fP or \fBpcre16_compile2()\fP is still an 8-bit
+character string, zero-terminated.
+.
+.
+.SH "CALLOUTS"
+.rs
+.sp
+The \fIsubject\fP and \fImark\fP fields in the callout block that is passed to
+a callout function point to 16-bit vectors.
+.
+.
+.SH "TESTING"
+.rs
+.sp
+The \fBpcretest\fP program continues to operate with 8-bit input and output
+files, but it can be used for testing the 16-bit library. If it is run with the
+command line option \fB-16\fP, patterns and subject strings are converted from
+8-bit to 16-bit before being passed to PCRE, and the 16-bit library functions
+are used instead of the 8-bit ones. Returned 16-bit strings are converted to
+8-bit for output. If the 8-bit library was not compiled, \fBpcretest\fP
+defaults to 16-bit and the \fB-16\fP option is ignored.
+.P
+When PCRE is being built, the \fBRunTest\fP script that is called by "make
+check" uses the \fBpcretest\fP \fB-C\fP option to discover which of the 8-bit
+and 16-bit libraries has been built, and runs the tests appropriately.
+.
+.
+.SH "NOT SUPPORTED IN 16-BIT MODE"
+.rs
+.sp
+Not all the features of the 8-bit library are available with the 16-bit
+library. The C++ and POSIX wrapper functions support only the 8-bit library,
+and the \fBpcregrep\fP program is at present 8-bit only.
+.
+.
+.SH AUTHOR
+.rs
+.sp
+.nf
+Philip Hazel
+University Computing Service
+Cambridge CB2 3QH, England.
+.fi
+.
+.
+.SH REVISION
+.rs
+.sp
+.nf
+Last updated: 14 April 2012
+Copyright (c) 1997-2012 University of Cambridge.
+.fi
diff -Nru pcre3-8.12/doc/pcre_assign_jit_stack.3 pcre3-8.31/doc/pcre_assign_jit_stack.3
--- pcre3-8.12/doc/pcre_assign_jit_stack.3 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/pcre_assign_jit_stack.3 2012-05-26 14:21:10.000000000 +0000
@@ -0,0 +1,57 @@
+.TH PCRE_ASSIGN_JIT_STACK 3 "13 January 2012" "PCRE 8.30"
+.SH NAME
+PCRE - Perl-compatible regular expressions
+.SH SYNOPSIS
+.rs
+.sp
+.B #include
+.PP
+.SM
+.B void pcre_assign_jit_stack(pcre_extra *\fIextra\fP,
+.ti +5n
+.B pcre_jit_callback \fIcallback\fP, void *\fIdata\fP);
+.PP
+.B void pcre16_assign_jit_stack(pcre16_extra *\fIextra\fP,
+.ti +5n
+.B pcre16_jit_callback \fIcallback\fP, void *\fIdata\fP);
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function provides control over the memory used as a stack at run-time by a
+call to \fBpcre[16]_exec()\fP with a pattern that has been successfully
+compiled with JIT optimization. The arguments are:
+.sp
+ extra the data pointer returned by \fBpcre[16]_study()\fP
+ callback a callback function
+ data a JIT stack or a value to be passed to the callback
+ function
+.P
+If \fIcallback\fP is NULL and \fIdata\fP is NULL, an internal 32K block on
+the machine stack is used.
+.P
+If \fIcallback\fP is NULL and \fIdata\fP is not NULL, \fIdata\fP must
+be a valid JIT stack, the result of calling \fBpcre[16]_jit_stack_alloc()\fP.
+.P
+If \fIcallback\fP not NULL, it is called with \fIdata\fP as an argument at
+the start of matching, in order to set up a JIT stack. If the result is NULL,
+the internal 32K stack is used; otherwise the return value must be a valid JIT
+stack, the result of calling \fBpcre[16]_jit_stack_alloc()\fP.
+.P
+You may safely assign the same JIT stack to multiple patterns, as long as they
+are all matched in the same thread. In a multithread application, each thread
+must use its own JIT stack. For more details, see the
+.\" HREF
+\fBpcrejit\fP
+.\"
+page.
+.P
+There is a complete description of the PCRE native API in the
+.\" HREF
+\fBpcreapi\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcreposix\fP
+.\"
+page.
diff -Nru pcre3-8.12/doc/pcre_compile.3 pcre3-8.31/doc/pcre_compile.3
--- pcre3-8.12/doc/pcre_compile.3 2011-01-11 16:29:57.000000000 +0000
+++ pcre3-8.31/doc/pcre_compile.3 2012-05-26 14:21:10.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_COMPILE 3
+.TH PCRE_COMPILE 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -12,13 +12,19 @@
.B const char **\fIerrptr\fP, int *\fIerroffset\fP,
.ti +5n
.B const unsigned char *\fItableptr\fP);
+.PP
+.B pcre16 *pcre16_compile(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP,
+.ti +5n
+.B const char **\fIerrptr\fP, int *\fIerroffset\fP,
+.ti +5n
+.B const unsigned char *\fItableptr\fP);
.
.SH DESCRIPTION
.rs
.sp
This function compiles a regular expression into an internal form. It is the
-same as \fBpcre_compile2()\fP, except for the absence of the \fIerrorcodeptr\fP
-argument. Its arguments are:
+same as \fBpcre[16]_compile2()\fP, except for the absence of the
+\fIerrorcodeptr\fP argument. Its arguments are:
.sp
\fIpattern\fP A zero-terminated string containing the
regular expression to be compiled
@@ -38,7 +44,7 @@
PCRE_DOLLAR_ENDONLY $ not to match newline at end
PCRE_DOTALL . matches anything including NL
PCRE_DUPNAMES Allow duplicate names for subpatterns
- PCRE_EXTENDED Ignore whitespace and # comments
+ PCRE_EXTENDED Ignore white space and # comments
PCRE_EXTRA PCRE extra features
(not much use currently)
PCRE_FIRSTLINE Force matching to be before newline
@@ -52,15 +58,19 @@
PCRE_NEWLINE_LF Set LF as the newline sequence
PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren-
theses (named ones available)
+ PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16
+ validity (only relevant if
+ PCRE_UTF16 is set)
PCRE_NO_UTF8_CHECK Do not check the pattern for UTF-8
validity (only relevant if
PCRE_UTF8 is set)
PCRE_UCP Use Unicode properties for \ed, \ew, etc.
PCRE_UNGREEDY Invert greediness of quantifiers
- PCRE_UTF8 Run in UTF-8 mode
+ PCRE_UTF16 Run in \fBpcre16_compile()\fP UTF-16 mode
+ PCRE_UTF8 Run in \fBpcre_compile()\fP UTF-8 mode
.sp
-PCRE must be built with UTF-8 support in order to use PCRE_UTF8 and
-PCRE_NO_UTF8_CHECK, and with UCP support if PCRE_UCP is used.
+PCRE must be built with UTF support in order to use PCRE_UTF8/16 and
+PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used.
.P
The yield of the function is a pointer to a private data structure that
contains the compiled pattern, or NULL if an error was detected. Note that
diff -Nru pcre3-8.12/doc/pcre_compile2.3 pcre3-8.31/doc/pcre_compile2.3
--- pcre3-8.12/doc/pcre_compile2.3 2011-01-11 16:30:43.000000000 +0000
+++ pcre3-8.31/doc/pcre_compile2.3 2012-05-26 14:21:10.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_COMPILE2 3
+.TH PCRE_COMPILE2 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -14,13 +14,21 @@
.B const char **\fIerrptr\fP, int *\fIerroffset\fP,
.ti +5n
.B const unsigned char *\fItableptr\fP);
+.PP
+.B pcre16 *pcre16_compile2(PCRE_SPTR16 \fIpattern\fP, int \fIoptions\fP,
+.ti +5n
+.B int *\fIerrorcodeptr\fP,
+.ti +5n
+.B const char **\fIerrptr\fP, int *\fIerroffset\fP,
+.ti +5n
+.B const unsigned char *\fItableptr\fP);
.
.SH DESCRIPTION
.rs
.sp
This function compiles a regular expression into an internal form. It is the
-same as \fBpcre_compile()\fP, except for the addition of the \fIerrorcodeptr\fP
-argument. The arguments are:
+same as \fBpcre[16]_compile()\fP, except for the addition of the
+\fIerrorcodeptr\fP argument. The arguments are:
.
.sp
\fIpattern\fP A zero-terminated string containing the
@@ -42,7 +50,7 @@
PCRE_DOLLAR_ENDONLY $ not to match newline at end
PCRE_DOTALL . matches anything including NL
PCRE_DUPNAMES Allow duplicate names for subpatterns
- PCRE_EXTENDED Ignore whitespace and # comments
+ PCRE_EXTENDED Ignore white space and # comments
PCRE_EXTRA PCRE extra features
(not much use currently)
PCRE_FIRSTLINE Force matching to be before newline
@@ -56,15 +64,19 @@
PCRE_NEWLINE_LF Set LF as the newline sequence
PCRE_NO_AUTO_CAPTURE Disable numbered capturing paren-
theses (named ones available)
+ PCRE_NO_UTF16_CHECK Do not check the pattern for UTF-16
+ validity (only relevant if
+ PCRE_UTF16 is set)
PCRE_NO_UTF8_CHECK Do not check the pattern for UTF-8
validity (only relevant if
PCRE_UTF8 is set)
PCRE_UCP Use Unicode properties for \ed, \ew, etc.
PCRE_UNGREEDY Invert greediness of quantifiers
- PCRE_UTF8 Run in UTF-8 mode
+ PCRE_UTF16 Run \fBpcre16_compile()\fP in UTF-16 mode
+ PCRE_UTF8 Run \fBpcre_compile()\fP in UTF-8 mode
.sp
-PCRE must be built with UTF-8 support in order to use PCRE_UTF8 and
-PCRE_NO_UTF8_CHECK, and with UCP support if PCRE_UCP is used.
+PCRE must be built with UTF support in order to use PCRE_UTF8/16 and
+PCRE_NO_UTF8/16_CHECK, and with UCP support if PCRE_UCP is used.
.P
The yield of the function is a pointer to a private data structure that
contains the compiled pattern, or NULL if an error was detected. Note that
diff -Nru pcre3-8.12/doc/pcre_config.3 pcre3-8.31/doc/pcre_config.3
--- pcre3-8.12/doc/pcre_config.3 2011-01-11 16:31:34.000000000 +0000
+++ pcre3-8.31/doc/pcre_config.3 2012-03-31 16:35:31.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_CONFIG 3
+.TH PCRE_CONFIG 3 "21 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -8,19 +8,28 @@
.PP
.SM
.B int pcre_config(int \fIwhat\fP, void *\fIwhere\fP);
+.PP
+.B int pcre16_config(int \fIwhat\fP, void *\fIwhere\fP);
.
.SH DESCRIPTION
.rs
.sp
This function makes it possible for a client program to find out which optional
-features are available in the version of the PCRE library it is using. Its
+features are available in the version of the PCRE library it is using. The
arguments are as follows:
.sp
\fIwhat\fP A code specifying what information is required
\fIwhere\fP Points to where to put the data
.sp
-The available codes are:
-.sp
+The \fIwhere\fP argument must point to an integer variable, except for
+PCRE_CONFIG_MATCH_LIMIT and PCRE_CONFIG_MATCH_LIMIT_RECURSION, when it must
+point to an unsigned long integer. The available codes are:
+.sp
+ PCRE_CONFIG_JIT Availability of just-in-time compiler
+ support (1=yes 0=no)
+ PCRE_CONFIG_JITTARGET String containing information about the
+ target architecture for the JIT compiler,
+ or NULL if there is no JIT support
PCRE_CONFIG_LINK_SIZE Internal link size: 2, 3, or 4
PCRE_CONFIG_MATCH_LIMIT Internal resource limit
PCRE_CONFIG_MATCH_LIMIT_RECURSION
@@ -35,16 +44,20 @@
0 all Unicode line endings
1 CR, LF, or CRLF only
PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
- Threshold of return slots, above
- which \fBmalloc()\fP is used by
- the POSIX API
+ Threshold of return slots, above which
+ \fBmalloc()\fP is used by the POSIX API
PCRE_CONFIG_STACKRECURSE Recursion implementation (1=stack 0=heap)
- PCRE_CONFIG_UTF8 Availability of UTF-8 support (1=yes 0=no)
+ PCRE_CONFIG_UTF16 Availability of UTF-16 support (1=yes
+ 0=no); option for \fBpcre16_config()\fP
+ PCRE_CONFIG_UTF8 Availability of UTF-8 support (1=yes 0=no);
+ option for \fBpcre_config()\fP
PCRE_CONFIG_UNICODE_PROPERTIES
Availability of Unicode property support
(1=yes 0=no)
.sp
-The function yields 0 on success or PCRE_ERROR_BADOPTION otherwise.
+The function yields 0 on success or PCRE_ERROR_BADOPTION otherwise. That error
+is also given if PCRE_CONFIG_UTF16 is passed to \fBpcre_config()\fP or if
+PCRE_CONFIG_UTF8 is passed to \fBpcre16_config()\fP.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcre_copy_named_substring.3 pcre3-8.31/doc/pcre_copy_named_substring.3
--- pcre3-8.12/doc/pcre_copy_named_substring.3 2007-03-06 11:45:55.000000000 +0000
+++ pcre3-8.31/doc/pcre_copy_named_substring.3 2012-03-31 16:36:06.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_COPY_NAMED_SUBSTRING 3
+.TH PCRE_COPY_NAMED_SUBSTRING 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -14,6 +14,14 @@
.B int \fIstringcount\fP, const char *\fIstringname\fP,
.ti +5n
.B char *\fIbuffer\fP, int \fIbuffersize\fP);
+.PP
+.B int pcre16_copy_named_substring(const pcre16 *\fIcode\fP,
+.ti +5n
+.B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP,
+.ti +5n
+.B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP,
+.ti +5n
+.B PCRE_UCHAR16 *\fIbuffer\fP, int \fIbuffersize\fP);
.
.SH DESCRIPTION
.rs
@@ -23,8 +31,8 @@
.sp
\fIcode\fP Pattern that was successfully matched
\fIsubject\fP Subject that has been successfully matched
- \fIovector\fP Offset vector that \fBpcre_exec()\fP used
- \fIstringcount\fP Value returned by \fBpcre_exec()\fP
+ \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used
+ \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP
\fIstringname\fP Name of the required substring
\fIbuffer\fP Buffer to receive the string
\fIbuffersize\fP Size of buffer
diff -Nru pcre3-8.12/doc/pcre_copy_substring.3 pcre3-8.31/doc/pcre_copy_substring.3
--- pcre3-8.12/doc/pcre_copy_substring.3 2007-03-06 11:45:49.000000000 +0000
+++ pcre3-8.31/doc/pcre_copy_substring.3 2012-03-31 16:36:26.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_COPY_SUBSTRING 3
+.TH PCRE_COPY_SUBSTRING 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -12,6 +12,12 @@
.B int \fIstringcount\fP, int \fIstringnumber\fP, char *\fIbuffer\fP,
.ti +5n
.B int \fIbuffersize\fP);
+.PP
+.B int pcre16_copy_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP,
+.ti +5n
+.B int \fIstringcount\fP, int \fIstringnumber\fP, PCRE_UCHAR16 *\fIbuffer\fP,
+.ti +5n
+.B int \fIbuffersize\fP);
.
.SH DESCRIPTION
.rs
@@ -20,8 +26,8 @@
buffer. The arguments are:
.sp
\fIsubject\fP Subject that has been successfully matched
- \fIovector\fP Offset vector that \fBpcre_exec()\fP used
- \fIstringcount\fP Value returned by \fBpcre_exec()\fP
+ \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used
+ \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP
\fIstringnumber\fP Number of the required substring
\fIbuffer\fP Buffer to receive the string
\fIbuffersize\fP Size of buffer
diff -Nru pcre3-8.12/doc/pcre_dfa_exec.3 pcre3-8.31/doc/pcre_dfa_exec.3
--- pcre3-8.12/doc/pcre_dfa_exec.3 2009-10-05 10:40:30.000000000 +0000
+++ pcre3-8.31/doc/pcre_dfa_exec.3 2012-03-31 16:36:55.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_DFA_EXEC 3
+.TH PCRE_DFA_EXEC 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -14,6 +14,14 @@
.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP,
.ti +5n
.B int *\fIworkspace\fP, int \fIwscount\fP);
+.PP
+.B int pcre16_dfa_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP,"
+.ti +5n
+.B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP,
+.ti +5n
+.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP,
+.ti +5n
+.B int *\fIworkspace\fP, int \fIwscount\fP);
.
.SH DESCRIPTION
.rs
@@ -21,10 +29,11 @@
This function matches a compiled regular expression against a given subject
string, using an alternative matching algorithm that scans the subject string
just once (\fInot\fP Perl-compatible). Note that the main, Perl-compatible,
-matching function is \fBpcre_exec()\fP. The arguments for this function are:
+matching function is \fBpcre[16]_exec()\fP. The arguments for this function
+are:
.sp
\fIcode\fP Points to the compiled pattern
- \fIextra\fP Points to an associated \fBpcre_extra\fP structure,
+ \fIextra\fP Points to an associated \fBpcre[16]_extra\fP structure,
or is NULL
\fIsubject\fP Points to the subject string
\fIlength\fP Length of the subject string, in bytes
@@ -52,6 +61,9 @@
PCRE_NOTEMPTY_ATSTART An empty string at the start of the subject
is not a valid match
PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations
+ PCRE_NO_UTF16_CHECK Do not check the subject for UTF-16
+ validity (only relevant if PCRE_UTF16
+ was set at compile time)
PCRE_NO_UTF8_CHECK Do not check the subject for UTF-8
validity (only relevant if PCRE_UTF8
was set at compile time)
@@ -73,19 +85,23 @@
.\"
page.
.P
-A \fBpcre_extra\fP structure contains the following fields:
+A \fBpcre[16]_extra\fP structure contains the following fields:
.sp
- \fIflags\fP Bits indicating which fields are set
- \fIstudy_data\fP Opaque data from \fBpcre_study()\fP
- \fImatch_limit\fP Limit on internal resource use
+ \fIflags\fP Bits indicating which fields are set
+ \fIstudy_data\fP Opaque data from \fBpcre[16]_study()\fP
+ \fImatch_limit\fP Limit on internal resource use
\fImatch_limit_recursion\fP Limit on internal recursion depth
- \fIcallout_data\fP Opaque data passed back to callouts
- \fItables\fP Points to character tables or is NULL
+ \fIcallout_data\fP Opaque data passed back to callouts
+ \fItables\fP Points to character tables or is NULL
+ \fImark\fP For passing back a *MARK pointer
+ \fIexecutable_jit\fP Opaque data from JIT compilation
.sp
The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT,
-PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, and
-PCRE_EXTRA_TABLES. For this matching function, the \fImatch_limit\fP and
-\fImatch_limit_recursion\fP fields are not used, and must not be set.
+PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA,
+PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT. For this
+matching function, the \fImatch_limit\fP and \fImatch_limit_recursion\fP fields
+are not used, and must not be set. The PCRE_EXTRA_EXECUTABLE_JIT flag and
+the corresponding variable are ignored.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcre_exec.3 pcre3-8.31/doc/pcre_exec.3
--- pcre3-8.12/doc/pcre_exec.3 2010-10-22 10:13:55.000000000 +0000
+++ pcre3-8.31/doc/pcre_exec.3 2012-03-31 16:37:09.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_EXEC 3
+.TH PCRE_EXEC 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -12,6 +12,12 @@
.B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP,
.ti +5n
.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP);
+.PP
+.B int pcre16_exec(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP,"
+.ti +5n
+.B "PCRE_SPTR16 \fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP,
+.ti +5n
+.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP);
.
.SH DESCRIPTION
.rs
@@ -21,7 +27,7 @@
offsets to captured substrings. Its arguments are:
.sp
\fIcode\fP Points to the compiled pattern
- \fIextra\fP Points to an associated \fBpcre_extra\fP structure,
+ \fIextra\fP Points to an associated \fBpcre[16]_extra\fP structure,
or is NULL
\fIsubject\fP Points to the subject string
\fIlength\fP Length of the subject string, in bytes
@@ -47,6 +53,9 @@
PCRE_NOTEMPTY_ATSTART An empty string at the start of the subject
is not a valid match
PCRE_NO_START_OPTIMIZE Do not do "start-match" optimizations
+ PCRE_NO_UTF16_CHECK Do not check the subject for UTF-16
+ validity (only relevant if PCRE_UTF16
+ was set at compile time)
PCRE_NO_UTF8_CHECK Do not check the subject for UTF-8
validity (only relevant if PCRE_UTF8
was set at compile time)
@@ -61,16 +70,18 @@
.\"
page. A \fBpcre_extra\fP structure contains the following fields:
.sp
- \fIflags\fP Bits indicating which fields are set
- \fIstudy_data\fP Opaque data from \fBpcre_study()\fP
- \fImatch_limit\fP Limit on internal resource use
+ \fIflags\fP Bits indicating which fields are set
+ \fIstudy_data\fP Opaque data from \fBpcre[16]_study()\fP
+ \fImatch_limit\fP Limit on internal resource use
\fImatch_limit_recursion\fP Limit on internal recursion depth
- \fIcallout_data\fP Opaque data passed back to callouts
- \fItables\fP Points to character tables or is NULL
+ \fIcallout_data\fP Opaque data passed back to callouts
+ \fItables\fP Points to character tables or is NULL
+ \fImark\fP For passing back a *MARK pointer
+ \fIexecutable_jit\fP Opaque data from JIT compilation
.sp
The flag bits are PCRE_EXTRA_STUDY_DATA, PCRE_EXTRA_MATCH_LIMIT,
-PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA, and
-PCRE_EXTRA_TABLES.
+PCRE_EXTRA_MATCH_LIMIT_RECURSION, PCRE_EXTRA_CALLOUT_DATA,
+PCRE_EXTRA_TABLES, PCRE_EXTRA_MARK and PCRE_EXTRA_EXECUTABLE_JIT.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcre_free_study.3 pcre3-8.31/doc/pcre_free_study.3
--- pcre3-8.12/doc/pcre_free_study.3 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/pcre_free_study.3 2012-03-31 16:37:20.000000000 +0000
@@ -0,0 +1,29 @@
+.TH PCRE_FREE_STUDY 3 "13 January 2012" "PCRE 8.30"
+.SH NAME
+PCRE - Perl-compatible regular expressions
+.SH SYNOPSIS
+.rs
+.sp
+.B #include
+.PP
+.SM
+.B void pcre_free_study(pcre_extra *\fIextra\fP);
+.PP
+.B void pcre16_free_study(pcre16_extra *\fIextra\fP);
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function is used to free the memory used for the data generated by a call
+to \fBpcre[16]_study()\fP when it is no longer needed. The argument must be the
+result of such a call.
+.P
+There is a complete description of the PCRE native API in the
+.\" HREF
+\fBpcreapi\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcreposix\fP
+.\"
+page.
diff -Nru pcre3-8.12/doc/pcre_free_substring.3 pcre3-8.31/doc/pcre_free_substring.3
--- pcre3-8.12/doc/pcre_free_substring.3 2007-03-06 11:45:22.000000000 +0000
+++ pcre3-8.31/doc/pcre_free_substring.3 2012-03-31 16:37:38.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_FREE_SUBSTRING 3
+.TH PCRE_FREE_SUBSTRING 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -8,13 +8,15 @@
.PP
.SM
.B void pcre_free_substring(const char *\fIstringptr\fP);
+.PP
+.B void pcre16_free_substring(PCRE_SPTR16 \fIstringptr\fP);
.
.SH DESCRIPTION
.rs
.sp
This is a convenience function for freeing the store obtained by a previous
-call to \fBpcre_get_substring()\fP or \fBpcre_get_named_substring()\fP. Its
-only argument is a pointer to the string.
+call to \fBpcre[16]_get_substring()\fP or \fBpcre[16]_get_named_substring()\fP.
+Its only argument is a pointer to the string.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcre_free_substring_list.3 pcre3-8.31/doc/pcre_free_substring_list.3
--- pcre3-8.12/doc/pcre_free_substring_list.3 2007-03-06 11:45:13.000000000 +0000
+++ pcre3-8.31/doc/pcre_free_substring_list.3 2012-03-31 16:37:46.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_FREE_SUBSTRING_LIST 3
+.TH PCRE_FREE_SUBSTRING_LIST 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -8,13 +8,15 @@
.PP
.SM
.B void pcre_free_substring_list(const char **\fIstringptr\fP);
+.PP
+.B void pcre16_free_substring_list(PCRE_SPTR16 *\fIstringptr\fP);
.
.SH DESCRIPTION
.rs
.sp
This is a convenience function for freeing the store obtained by a previous
-call to \fBpcre_get_substring_list()\fP. Its only argument is a pointer to the
-list of string pointers.
+call to \fBpcre[16]_get_substring_list()\fP. Its only argument is a pointer to
+the list of string pointers.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcre_fullinfo.3 pcre3-8.31/doc/pcre_fullinfo.3
--- pcre3-8.12/doc/pcre_fullinfo.3 2009-10-05 10:40:30.000000000 +0000
+++ pcre3-8.31/doc/pcre_fullinfo.3 2012-03-31 16:38:07.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_FULLINFO 3
+.TH PCRE_FULLINFO 3 "21 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -10,6 +10,10 @@
.B int pcre_fullinfo(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP,"
.ti +5n
.B int \fIwhat\fP, void *\fIwhere\fP);
+.PP
+.B int pcre16_fullinfo(const pcre16 *\fIcode\fP, "const pcre16_extra *\fIextra\fP,"
+.ti +5n
+.B int \fIwhat\fP, void *\fIwhere\fP);
.
.SH DESCRIPTION
.rs
@@ -17,7 +21,7 @@
This function returns information about a compiled pattern. Its arguments are:
.sp
\fIcode\fP Compiled regular expression
- \fIextra\fP Result of \fBpcre_study()\fP or NULL
+ \fIextra\fP Result of \fBpcre[16]_study()\fP or NULL
\fIwhat\fP What information is required
\fIwhere\fP Where to put the information
.sp
@@ -26,13 +30,16 @@
PCRE_INFO_BACKREFMAX Number of highest back reference
PCRE_INFO_CAPTURECOUNT Number of capturing subpatterns
PCRE_INFO_DEFAULT_TABLES Pointer to default tables
- PCRE_INFO_FIRSTBYTE Fixed first byte for a match, or
+ PCRE_INFO_FIRSTBYTE Fixed first data unit for a match, or
-1 for start of string
or after newline, or
-2 otherwise
- PCRE_INFO_FIRSTTABLE Table of first bytes (after studying)
+ PCRE_INFO_FIRSTTABLE Table of first data units (after studying)
+ PCRE_INFO_HASCRORLF Return 1 if explicit CR or LF matches exist
PCRE_INFO_JCHANGED Return 1 if (?J) or (?-J) was used
- PCRE_INFO_LASTLITERAL Literal last byte required
+ PCRE_INFO_JIT Return 1 after successful JIT compilation
+ PCRE_INFO_JITSIZE Size of JIT compiled code
+ PCRE_INFO_LASTLITERAL Literal last data unit required
PCRE_INFO_MINLENGTH Lower bound length of matching strings
PCRE_INFO_NAMECOUNT Number of named subpatterns
PCRE_INFO_NAMEENTRYSIZE Size of name table entry
@@ -43,6 +50,16 @@
PCRE_INFO_SIZE Size of compiled pattern
PCRE_INFO_STUDYSIZE Size of study data
.sp
+The \fIwhere\fP argument must point to an integer variable, except for the
+following \fIwhat\fP values:
+.sp
+ PCRE_INFO_DEFAULT_TABLES const unsigned char *
+ PCRE_INFO_FIRSTTABLE const unsigned char *
+ PCRE_INFO_NAMETABLE PCRE_SPTR16 (16-bit library)
+ PCRE_INFO_NAMETABLE const unsigned char * (8-bit library)
+ PCRE_INFO_OPTIONS unsigned long int
+ PCRE_INFO_SIZE size_t
+.sp
The yield of the function is zero on success or:
.sp
PCRE_ERROR_NULL the argument \fIcode\fP was NULL
diff -Nru pcre3-8.12/doc/pcre_get_named_substring.3 pcre3-8.31/doc/pcre_get_named_substring.3
--- pcre3-8.12/doc/pcre_get_named_substring.3 2007-03-06 11:45:03.000000000 +0000
+++ pcre3-8.31/doc/pcre_get_named_substring.3 2012-03-31 16:38:26.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_GET_NAMED_SUBSTRING 3
+.TH PCRE_GET_NAMED_SUBSTRING 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -14,6 +14,14 @@
.B int \fIstringcount\fP, const char *\fIstringname\fP,
.ti +5n
.B const char **\fIstringptr\fP);
+.PP
+.B int pcre16_get_named_substring(const pcre16 *\fIcode\fP,
+.ti +5n
+.B PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP,
+.ti +5n
+.B int \fIstringcount\fP, PCRE_SPTR16 \fIstringname\fP,
+.ti +5n
+.B PCRE_SPTR16 *\fIstringptr\fP);
.
.SH DESCRIPTION
.rs
@@ -23,16 +31,17 @@
.sp
\fIcode\fP Compiled pattern
\fIsubject\fP Subject that has been successfully matched
- \fIovector\fP Offset vector that \fBpcre_exec()\fP used
- \fIstringcount\fP Value returned by \fBpcre_exec()\fP
+ \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used
+ \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP
\fIstringname\fP Name of the required substring
\fIstringptr\fP Where to put the string pointer
.sp
The memory in which the substring is placed is obtained by calling
-\fBpcre_malloc()\fP. The convenience function \fBpcre_free_substring()\fP can
-be used to free it when it is no longer needed. The yield of the function is
-the length of the extracted substring, PCRE_ERROR_NOMEMORY if sufficient memory
-could not be obtained, or PCRE_ERROR_NOSUBSTRING if the string name is invalid.
+\fBpcre[16]_malloc()\fP. The convenience function
+\fBpcre[16]_free_substring()\fP can be used to free it when it is no longer
+needed. The yield of the function is the length of the extracted substring,
+PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or
+PCRE_ERROR_NOSUBSTRING if the string name is invalid.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcre_get_stringnumber.3 pcre3-8.31/doc/pcre_get_stringnumber.3
--- pcre3-8.12/doc/pcre_get_stringnumber.3 2007-03-06 11:44:53.000000000 +0000
+++ pcre3-8.31/doc/pcre_get_stringnumber.3 2012-03-31 16:38:38.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_GET_STRINGNUMBER 3
+.TH PCRE_GET_STRINGNUMBER 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -10,6 +10,10 @@
.B int pcre_get_stringnumber(const pcre *\fIcode\fP,
.ti +5n
.B const char *\fIname\fP);
+.PP
+.B int pcre16_get_stringnumber(const pcre16 *\fIcode\fP,
+.ti +5n
+.B PCRE_SPTR16 \fIname\fP);
.
.SH DESCRIPTION
.rs
@@ -23,8 +27,8 @@
The yield of the function is the number of the parenthesis if the name is
found, or PCRE_ERROR_NOSUBSTRING otherwise. When duplicate names are allowed
(PCRE_DUPNAMES is set), it is not defined which of the numbers is returned by
-\fBpcre_get_stringnumber()\fP. You can obtain the complete list by calling
-\fBpcre_get_stringtable_entries()\fP.
+\fBpcre[16]_get_stringnumber()\fP. You can obtain the complete list by calling
+\fBpcre[16]_get_stringtable_entries()\fP.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcre_get_stringtable_entries.3 pcre3-8.31/doc/pcre_get_stringtable_entries.3
--- pcre3-8.12/doc/pcre_get_stringtable_entries.3 2007-03-06 11:44:45.000000000 +0000
+++ pcre3-8.31/doc/pcre_get_stringtable_entries.3 2012-03-31 16:38:56.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_GET_STRINGTABLE_ENTRIES 3
+.TH PCRE_GET_STRINGTABLE_ENTRIES 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -10,6 +10,10 @@
.B int pcre_get_stringtable_entries(const pcre *\fIcode\fP,
.ti +5n
.B const char *\fIname\fP, char **\fIfirst\fP, char **\fIlast\fP);
+.PP
+.B int pcre16_get_stringtable_entries(const pcre16 *\fIcode\fP,
+.ti +5n
+.B PCRE_SPTR16 \fIname\fP, PCRE_UCHAR16 **\fIfirst\fP, PCRE_UCHAR16 **\fIlast\fP);
.
.SH DESCRIPTION
.rs
@@ -17,7 +21,7 @@
This convenience function finds, for a compiled pattern, the first and last
entries for a given name in the table that translates capturing parenthesis
names into numbers. When names are required to be unique (PCRE_DUPNAMES is
-\fInot\fP set), it is usually easier to use \fBpcre_get_stringnumber()\fP
+\fInot\fP set), it is usually easier to use \fBpcre[16]_get_stringnumber()\fP
instead.
.sp
\fIcode\fP Compiled regular expression
diff -Nru pcre3-8.12/doc/pcre_get_substring.3 pcre3-8.31/doc/pcre_get_substring.3
--- pcre3-8.12/doc/pcre_get_substring.3 2007-03-06 11:44:37.000000000 +0000
+++ pcre3-8.31/doc/pcre_get_substring.3 2012-03-31 16:39:09.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_GET_SUBSTRING 3
+.TH PCRE_GET_SUBSTRING 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -12,6 +12,12 @@
.B int \fIstringcount\fP, int \fIstringnumber\fP,
.ti +5n
.B const char **\fIstringptr\fP);
+.PP
+.B int pcre16_get_substring(PCRE_SPTR16 \fIsubject\fP, int *\fIovector\fP,
+.ti +5n
+.B int \fIstringcount\fP, int \fIstringnumber\fP,
+.ti +5n
+.B PCRE_SPTR16 *\fIstringptr\fP);
.
.SH DESCRIPTION
.rs
@@ -20,16 +26,17 @@
arguments are:
.sp
\fIsubject\fP Subject that has been successfully matched
- \fIovector\fP Offset vector that \fBpcre_exec()\fP used
- \fIstringcount\fP Value returned by \fBpcre_exec()\fP
+ \fIovector\fP Offset vector that \fBpcre[16]_exec()\fP used
+ \fIstringcount\fP Value returned by \fBpcre[16]_exec()\fP
\fIstringnumber\fP Number of the required substring
\fIstringptr\fP Where to put the string pointer
.sp
The memory in which the substring is placed is obtained by calling
-\fBpcre_malloc()\fP. The convenience function \fBpcre_free_substring()\fP can
-be used to free it when it is no longer needed. The yield of the function is
-the length of the substring, PCRE_ERROR_NOMEMORY if sufficient memory could not
-be obtained, or PCRE_ERROR_NOSUBSTRING if the string number is invalid.
+\fBpcre[16]_malloc()\fP. The convenience function
+\fBpcre[16]_free_substring()\fP can be used to free it when it is no longer
+needed. The yield of the function is the length of the substring,
+PCRE_ERROR_NOMEMORY if sufficient memory could not be obtained, or
+PCRE_ERROR_NOSUBSTRING if the string number is invalid.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcre_get_substring_list.3 pcre3-8.31/doc/pcre_get_substring_list.3
--- pcre3-8.12/doc/pcre_get_substring_list.3 2007-03-06 11:44:30.000000000 +0000
+++ pcre3-8.31/doc/pcre_get_substring_list.3 2012-03-31 16:39:22.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_GET_SUBSTRING_LIST 3
+.TH PCRE_GET_SUBSTRING_LIST 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -10,6 +10,10 @@
.B int pcre_get_substring_list(const char *\fIsubject\fP,
.ti +5n
.B int *\fIovector\fP, int \fIstringcount\fP, "const char ***\fIlistptr\fP);"
+.PP
+.B int pcre16_get_substring_list(PCRE_SPTR16 \fIsubject\fP,
+.ti +5n
+.B int *\fIovector\fP, int \fIstringcount\fP, "PCRE_SPTR16 **\fIlistptr\fP);"
.
.SH DESCRIPTION
.rs
@@ -18,17 +22,17 @@
substrings. The arguments are:
.sp
\fIsubject\fP Subject that has been successfully matched
- \fIovector\fP Offset vector that \fBpcre_exec\fP used
- \fIstringcount\fP Value returned by \fBpcre_exec\fP
+ \fIovector\fP Offset vector that \fBpcre[16]_exec\fP used
+ \fIstringcount\fP Value returned by \fBpcre[16]_exec\fP
\fIlistptr\fP Where to put a pointer to the list
.sp
The memory in which the substrings and the list are placed is obtained by
-calling \fBpcre_malloc()\fP. The convenience function
-\fBpcre_free_substring_list()\fP can be used to free it when it is no longer
-needed. A pointer to a list of pointers is put in the variable whose address is
-in \fIlistptr\fP. The list is terminated by a NULL pointer. The yield of the
-function is zero on success or PCRE_ERROR_NOMEMORY if sufficient memory could
-not be obtained.
+calling \fBpcre[16]_malloc()\fP. The convenience function
+\fBpcre[16]_free_substring_list()\fP can be used to free it when it is no
+longer needed. A pointer to a list of pointers is put in the variable whose
+address is in \fIlistptr\fP. The list is terminated by a NULL pointer. The
+yield of the function is zero on success or PCRE_ERROR_NOMEMORY if sufficient
+memory could not be obtained.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcre_info.3 pcre3-8.31/doc/pcre_info.3
--- pcre3-8.12/doc/pcre_info.3 2007-03-06 11:44:22.000000000 +0000
+++ pcre3-8.31/doc/pcre_info.3 1970-01-01 00:00:00.000000000 +0000
@@ -1,26 +0,0 @@
-.TH PCRE_INFO 3
-.SH NAME
-PCRE - Perl-compatible regular expressions
-.SH SYNOPSIS
-.rs
-.sp
-.B #include
-.PP
-.SM
-.B int pcre_info(const pcre *\fIcode\fP, int *\fIoptptr\fP, int
-.B *\fIfirstcharptr\fP);
-.
-.SH DESCRIPTION
-.rs
-.sp
-This function is obsolete. You should be using \fBpcre_fullinfo()\fP instead.
-.P
-There is a complete description of the PCRE native API in the
-.\" HREF
-\fBpcreapi\fP
-.\"
-page and a description of the POSIX API in the
-.\" HREF
-\fBpcreposix\fP
-.\"
-page.
diff -Nru pcre3-8.12/doc/pcre_jit_stack_alloc.3 pcre3-8.31/doc/pcre_jit_stack_alloc.3
--- pcre3-8.12/doc/pcre_jit_stack_alloc.3 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/pcre_jit_stack_alloc.3 2012-05-26 14:21:10.000000000 +0000
@@ -0,0 +1,41 @@
+.TH PCRE_JIT_STACK_ALLOC 3 "21 January 2012" "PCRE 8.30"
+.SH NAME
+PCRE - Perl-compatible regular expressions
+.SH SYNOPSIS
+.rs
+.sp
+.B #include
+.PP
+.SM
+.B pcre_jit_stack *pcre_jit_stack_alloc(int \fIstartsize\fP,
+.ti +5n
+.B int \fImaxsize\fP);
+.PP
+.B pcre16_jit_stack *pcre16_jit_stack_alloc(int \fIstartsize\fP,
+.ti +5n
+.B int \fImaxsize\fP);
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function is used to create a stack for use by the code compiled by the JIT
+optimization of \fBpcre[16]_study()\fP. The arguments are a starting size for
+the stack, and a maximum size to which it is allowed to grow. The result can be
+passed to the JIT run-time code by \fBpcre[16]_assign_jit_stack()\fP, or that
+function can set up a callback for obtaining a stack. A maximum stack size of
+512K to 1M should be more than enough for any pattern. For more details, see
+the
+.\" HREF
+\fBpcrejit\fP
+.\"
+page.
+.P
+There is a complete description of the PCRE native API in the
+.\" HREF
+\fBpcreapi\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcreposix\fP
+.\"
+page.
diff -Nru pcre3-8.12/doc/pcre_jit_stack_free.3 pcre3-8.31/doc/pcre_jit_stack_free.3
--- pcre3-8.12/doc/pcre_jit_stack_free.3 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/pcre_jit_stack_free.3 2012-03-31 16:40:02.000000000 +0000
@@ -0,0 +1,33 @@
+.TH PCRE_JIT_STACK_FREE 3 "13 January 2012" "PCRE 8.30"
+.SH NAME
+PCRE - Perl-compatible regular expressions
+.SH SYNOPSIS
+.rs
+.sp
+.B #include
+.PP
+.SM
+.B void pcre_jit_stack_free(pcre_jit_stack *\fIstack\fP);
+.PP
+.B void pcre16_jit_stack_free(pcre16_jit_stack *\fIstack\fP);
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function is used to free a JIT stack that was created by
+\fBpcre[16]_jit_stack_alloc()\fP when it is no longer needed. For more details,
+see the
+.\" HREF
+\fBpcrejit\fP
+.\"
+page.
+.P
+There is a complete description of the PCRE native API in the
+.\" HREF
+\fBpcreapi\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcreposix\fP
+.\"
+page.
diff -Nru pcre3-8.12/doc/pcre_maketables.3 pcre3-8.31/doc/pcre_maketables.3
--- pcre3-8.12/doc/pcre_maketables.3 2007-03-06 11:44:14.000000000 +0000
+++ pcre3-8.31/doc/pcre_maketables.3 2012-03-31 16:40:18.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_MAKETABLES 3
+.TH PCRE_MAKETABLES 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -8,15 +8,17 @@
.PP
.SM
.B const unsigned char *pcre_maketables(void);
+.PP
+.B const unsigned char *pcre16_maketables(void);
.
.SH DESCRIPTION
.rs
.sp
This function builds a set of character tables for character values less than
-256. These can be passed to \fBpcre_compile()\fP to override PCRE's internal,
-built-in tables (which were made by \fBpcre_maketables()\fP when PCRE was
-compiled). You might want to do this if you are using a non-standard locale.
-The function yields a pointer to the tables.
+256. These can be passed to \fBpcre[16]_compile()\fP to override PCRE's
+internal, built-in tables (which were made by \fBpcre[16]_maketables()\fP when
+PCRE was compiled). You might want to do this if you are using a non-standard
+locale. The function yields a pointer to the tables.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcre_pattern_to_host_byte_order.3 pcre3-8.31/doc/pcre_pattern_to_host_byte_order.3
--- pcre3-8.12/doc/pcre_pattern_to_host_byte_order.3 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/pcre_pattern_to_host_byte_order.3 2012-03-31 16:40:42.000000000 +0000
@@ -0,0 +1,43 @@
+.TH PCRE_PATTERN_TO_HOST_BYTE_ORDER 3 "21 January 2012" "PCRE 8.30"
+.SH NAME
+PCRE - Perl-compatible regular expressions
+.SH SYNOPSIS
+.rs
+.sp
+.B #include
+.PP
+.SM
+.B int pcre_pattern_to_host_byte_order(pcre *\fIcode\fP,
+.ti +5n
+.B pcre_extra *\fIextra\fP, const unsigned char *\fItables\fP);
+.PP
+.B int pcre16_pattern_to_host_byte_order(pcre16 *\fIcode\fP,
+.ti +5n
+.B pcre16_extra *\fIextra\fP, const unsigned char *\fItables\fP);
+.
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function ensures that the bytes in 2-byte and 4-byte values in a compiled
+pattern are in the correct order for the current host. It is useful when a
+pattern that has been compiled on one host is transferred to another that might
+have different endianness. The arguments are:
+.sp
+ \fIcode\fP A compiled regular expression
+ \fIextra\fP Points to an associated \fBpcre[16]_extra\fP structure,
+ or is NULL
+ \fItables\fP Pointer to character tables, or NULL to
+ set the built-in default
+.sp
+The result is 0 for success, a negative PCRE_ERROR_xxx value otherwise.
+.P
+There is a complete description of the PCRE native API in the
+.\" HREF
+\fBpcreapi\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcreposix\fP
+.\"
+page.
diff -Nru pcre3-8.12/doc/pcre_refcount.3 pcre3-8.31/doc/pcre_refcount.3
--- pcre3-8.12/doc/pcre_refcount.3 2007-03-06 11:44:03.000000000 +0000
+++ pcre3-8.31/doc/pcre_refcount.3 2012-03-31 16:40:58.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_REFCOUNT 3
+.TH PCRE_REFCOUNT 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -8,6 +8,8 @@
.PP
.SM
.B int pcre_refcount(pcre *\fIcode\fP, int \fIadjust\fP);
+.PP
+.B int pcre16_refcount(pcre16 *\fIcode\fP, int \fIadjust\fP);
.
.SH DESCRIPTION
.rs
diff -Nru pcre3-8.12/doc/pcre_study.3 pcre3-8.31/doc/pcre_study.3
--- pcre3-8.12/doc/pcre_study.3 2007-03-06 11:43:47.000000000 +0000
+++ pcre3-8.31/doc/pcre_study.3 2012-03-31 16:41:07.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_STUDY 3
+.TH PCRE_STUDY 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -10,6 +10,10 @@
.B pcre_extra *pcre_study(const pcre *\fIcode\fP, int \fIoptions\fP,
.ti +5n
.B const char **\fIerrptr\fP);
+.PP
+.B pcre16_extra *pcre16_study(const pcre16 *\fIcode\fP, int \fIoptions\fP,
+.ti +5n
+.B const char **\fIerrptr\fP);
.
.SH DESCRIPTION
.rs
@@ -18,18 +22,24 @@
be extracted that might speed up matching. Its arguments are:
.sp
\fIcode\fP A compiled regular expression
- \fIoptions\fP Options for \fBpcre_study()\fP
+ \fIoptions\fP Options for \fBpcre[16]_study()\fP
\fIerrptr\fP Where to put an error message
.sp
If the function succeeds, it returns a value that can be passed to
-\fBpcre_exec()\fP via its \fIextra\fP argument.
+\fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP via their \fIextra\fP
+arguments.
.P
If the function returns NULL, either it could not find any additional
information, or there was an error. You can tell the difference by looking at
the error value. It is NULL in first case.
.P
-There are currently no options defined; the value of the second argument should
-always be zero.
+The only option is PCRE_STUDY_JIT_COMPILE. It requests just-in-time compilation
+if possible. If PCRE has been compiled without JIT support, this option is
+ignored. See the
+.\" HREF
+\fBpcrejit\fP
+.\"
+page for further details.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcre_utf16_to_host_byte_order.3 pcre3-8.31/doc/pcre_utf16_to_host_byte_order.3
--- pcre3-8.12/doc/pcre_utf16_to_host_byte_order.3 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/pcre_utf16_to_host_byte_order.3 2012-03-31 16:41:25.000000000 +0000
@@ -0,0 +1,46 @@
+.TH PCRE_UTF16_TO_HOST_BYTE_ORDER 3 "21 January 2012" "PCRE 8.30"
+.SH NAME
+PCRE - Perl-compatible regular expressions
+.SH SYNOPSIS
+.rs
+.sp
+.B #include
+.PP
+.SM
+.B int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *\fIoutput\fP,
+.ti +5n
+.B PCRE_SPTR16 \fIinput\fP, int \fIlength\fP, int *\fIhost_byte_order\fP,
+.ti +5n
+.B int \fIkeep_boms\fP);
+.
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function, which exists only in the 16-bit library, converts a UTF-16
+string to the correct order for the current host, taking account of any byte
+order marks (BOMs) within the string. Its arguments are:
+.sp
+ \fIoutput\fP pointer to output buffer, may be the same as \fIinput\fP
+ \fIinput\fP pointer to input buffer
+ \fIlength\fP number of 16-bit units in the input, or negative for
+ a zero-terminated string
+ \fIhost_byte_order\fP a NULL value or a non-zero value pointed to means
+ start in host byte order
+ \fIkeep_boms\fP if non-zero, BOMs are copied to the output string
+.sp
+The result of the function is the number of 16-bit units placed into the output
+buffer, including the zero terminator if the string was zero-terminated.
+.P
+If \fIhost_byte_order\fP is not NULL, it is set to indicate the byte order that
+is current at the end of the string.
+.P
+There is a complete description of the PCRE native API in the
+.\" HREF
+\fBpcreapi\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcreposix\fP
+.\"
+page.
diff -Nru pcre3-8.12/doc/pcre_version.3 pcre3-8.31/doc/pcre_version.3
--- pcre3-8.12/doc/pcre_version.3 2013-03-27 06:36:17.000000000 +0000
+++ pcre3-8.31/doc/pcre_version.3 2012-03-31 16:41:37.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRE_VERSION 3
+.TH PCRE_VERSION 3 "13 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH SYNOPSIS
@@ -8,12 +8,15 @@
.PP
.SM
.B const char *pcre_version(void);
+.PP
+.B const char *pcre16_version(void);
.
.SH DESCRIPTION
.rs
.sp
-This function returns a character string that gives the version number of the
-PCRE library and the date of its release.
+This function (even in the 16-bit library) returns a zero-terminated, 8-bit
+character string that gives the version number of the PCRE library and the date
+of its release.
.P
There is a complete description of the PCRE native API in the
.\" HREF
diff -Nru pcre3-8.12/doc/pcreapi.3 pcre3-8.31/doc/pcreapi.3
--- pcre3-8.12/doc/pcreapi.3 2013-03-27 06:36:17.000000000 +0000
+++ pcre3-8.31/doc/pcreapi.3 2012-06-17 16:53:44.000000000 +0000
@@ -1,11 +1,13 @@
-.TH PCREAPI 3
+.TH PCREAPI 3 "04 May 2012" "PCRE 8.31"
.SH NAME
PCRE - Perl-compatible regular expressions
-.SH "PCRE NATIVE API"
-.rs
.sp
.B #include
-.PP
+.
+.
+.SH "PCRE NATIVE API BASIC FUNCTIONS"
+.rs
+.sp
.SM
.B pcre *pcre_compile(const char *\fIpattern\fP, int \fIoptions\fP,
.ti +5n
@@ -25,6 +27,8 @@
.ti +5n
.B const char **\fIerrptr\fP);
.PP
+.B void pcre_free_study(pcre_extra *\fIextra\fP);
+.PP
.B int pcre_exec(const pcre *\fIcode\fP, "const pcre_extra *\fIextra\fP,"
.ti +5n
.B "const char *\fIsubject\fP," int \fIlength\fP, int \fIstartoffset\fP,
@@ -38,7 +42,11 @@
.B int \fIoptions\fP, int *\fIovector\fP, int \fIovecsize\fP,
.ti +5n
.B int *\fIworkspace\fP, int \fIwscount\fP);
-.PP
+.
+.
+.SH "PCRE NATIVE API STRING EXTRACTION FUNCTIONS"
+.rs
+.sp
.B int pcre_copy_named_substring(const pcre *\fIcode\fP,
.ti +5n
.B const char *\fIsubject\fP, int *\fIovector\fP,
@@ -82,6 +90,18 @@
.B void pcre_free_substring(const char *\fIstringptr\fP);
.PP
.B void pcre_free_substring_list(const char **\fIstringptr\fP);
+.
+.
+.SH "PCRE NATIVE API AUXILIARY FUNCTIONS"
+.rs
+.sp
+.B pcre_jit_stack *pcre_jit_stack_alloc(int \fIstartsize\fP, int \fImaxsize\fP);
+.PP
+.B void pcre_jit_stack_free(pcre_jit_stack *\fIstack\fP);
+.PP
+.B void pcre_assign_jit_stack(pcre_extra *\fIextra\fP,
+.ti +5n
+.B pcre_jit_callback \fIcallback\fP, void *\fIdata\fP);
.PP
.B const unsigned char *pcre_maketables(void);
.PP
@@ -89,15 +109,20 @@
.ti +5n
.B int \fIwhat\fP, void *\fIwhere\fP);
.PP
-.B int pcre_info(const pcre *\fIcode\fP, int *\fIoptptr\fP, int
-.B *\fIfirstcharptr\fP);
-.PP
.B int pcre_refcount(pcre *\fIcode\fP, int \fIadjust\fP);
.PP
.B int pcre_config(int \fIwhat\fP, void *\fIwhere\fP);
.PP
.B const char *pcre_version(void);
.PP
+.B int pcre_pattern_to_host_byte_order(pcre *\fIcode\fP,
+.ti +5n
+.B pcre_extra *\fIextra\fP, const unsigned char *\fItables\fP);
+.
+.
+.SH "PCRE NATIVE API INDIRECTED FUNCTIONS"
+.rs
+.sp
.B void *(*pcre_malloc)(size_t);
.PP
.B void (*pcre_free)(void *);
@@ -109,28 +134,57 @@
.B int (*pcre_callout)(pcre_callout_block *);
.
.
+.SH "PCRE 8-BIT AND 16-BIT LIBRARIES"
+.rs
+.sp
+From release 8.30, PCRE can be compiled as a library for handling 16-bit
+character strings as well as, or instead of, the original library that handles
+8-bit character strings. To avoid too much complication, this document
+describes the 8-bit versions of the functions, with only occasional references
+to the 16-bit library.
+.P
+The 16-bit functions operate in the same way as their 8-bit counterparts; they
+just use different data types for their arguments and results, and their names
+start with \fBpcre16_\fP instead of \fBpcre_\fP. For every option that has UTF8
+in its name (for example, PCRE_UTF8), there is a corresponding 16-bit name with
+UTF8 replaced by UTF16. This facility is in fact just cosmetic; the 16-bit
+option names define the same bit values.
+.P
+References to bytes and UTF-8 in this document should be read as references to
+16-bit data quantities and UTF-16 when using the 16-bit library, unless
+specified otherwise. More details of the specific differences for the 16-bit
+library are given in the
+.\" HREF
+\fBpcre16\fP
+.\"
+page.
+.
+.
.SH "PCRE API OVERVIEW"
.rs
.sp
PCRE has its own native API, which is described in this document. There are
-also some wrapper functions that correspond to the POSIX regular expression
-API. These are described in the
+also some wrapper functions (for the 8-bit library only) that correspond to the
+POSIX regular expression API, but they do not give access to all the
+functionality. They are described in the
.\" HREF
\fBpcreposix\fP
.\"
documentation. Both of these APIs define a set of C function calls. A C++
-wrapper is distributed with PCRE. It is documented in the
+wrapper (again for the 8-bit library only) is also distributed with PCRE. It is
+documented in the
.\" HREF
\fBpcrecpp\fP
.\"
page.
.P
The native API C function prototypes are defined in the header file
-\fBpcre.h\fP, and on Unix systems the library itself is called \fBlibpcre\fP.
-It can normally be accessed by adding \fB-lpcre\fP to the command for linking
-an application that uses PCRE. The header file defines the macros PCRE_MAJOR
-and PCRE_MINOR to contain the major and minor release numbers for the library.
-Applications can use these to include support for different releases of PCRE.
+\fBpcre.h\fP, and on Unix-like systems the (8-bit) library itself is called
+\fBlibpcre\fP. It can normally be accessed by adding \fB-lpcre\fP to the
+command for linking an application that uses PCRE. The header file defines the
+macros PCRE_MAJOR and PCRE_MINOR to contain the major and minor release numbers
+for the library. Applications can use these to include support for different
+releases of PCRE.
.P
In a Windows environment, if you want to statically link an application program
against a non-dll \fBpcre.a\fP file, you must define PCRE_STATIC before
@@ -152,6 +206,19 @@
.\"
documentation describes how to compile and run it.
.P
+Just-in-time compiler support is an optional feature of PCRE that can be built
+in appropriate hardware environments. It greatly speeds up the matching
+performance of many patterns. Simple programs can easily request that it be
+used if available, by setting an option that is ignored when it is not
+relevant. More complicated programs might need to make use of the functions
+\fBpcre_jit_stack_alloc()\fP, \fBpcre_jit_stack_free()\fP, and
+\fBpcre_assign_jit_stack()\fP in order to control the JIT code's memory usage.
+These functions are discussed in the
+.\" HREF
+\fBpcrejit\fP
+.\"
+documentation.
+.P
A second matching function, \fBpcre_dfa_exec()\fP, which is not
Perl-compatible, is also provided. This uses a different algorithm for the
matching. The alternative algorithm finds all possible matches (at a given
@@ -186,10 +253,8 @@
internal tables that are generated when PCRE is built are used.
.P
The function \fBpcre_fullinfo()\fP is used to find out information about a
-compiled pattern; \fBpcre_info()\fP is an obsolete version that returns only
-some of the available information, but is retained for backwards compatibility.
-The function \fBpcre_version()\fP returns a pointer to a string containing the
-version of PCRE and its date of release.
+compiled pattern. The function \fBpcre_version()\fP returns a pointer to a
+string containing the version of PCRE and its date of release.
.P
The function \fBpcre_refcount()\fP maintains a reference count in a data block
containing a compiled pattern. This is provided for the benefit of
@@ -237,7 +302,7 @@
strings: a single CR (carriage return) character, a single LF (linefeed)
character, the two-character sequence CRLF, any of the three preceding, or any
Unicode newline sequence. The Unicode newline sequences are the three just
-mentioned, plus the single characters VT (vertical tab, U+000B), FF (formfeed,
+mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed,
U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS
(paragraph separator, U+2029).
.P
@@ -282,6 +347,13 @@
.P
The compiled form of a regular expression is not altered during matching, so
the same compiled pattern can safely be used by several threads at once.
+.P
+If the just-in-time optimization feature is being used, it needs separate
+memory stack areas for each thread. See the
+.\" HREF
+\fBpcrejit\fP
+.\"
+documentation for more details.
.
.
.SH "SAVING PRECOMPILED PATTERNS FOR LATER USE"
@@ -293,9 +365,10 @@
.\" HREF
\fBpcreprecompile\fP
.\"
-documentation. However, compiling a regular expression with one version of PCRE
-for use with a different version is not guaranteed to work and may cause
-crashes.
+documentation, which includes a description of the
+\fBpcre_pattern_to_host_byte_order()\fP function. However, compiling a regular
+expression with one version of PCRE for use with a different version is not
+guaranteed to work and may cause crashes.
.
.
.SH "CHECKING BUILD-TIME OPTIONS"
@@ -312,18 +385,40 @@
.P
The first argument for \fBpcre_config()\fP is an integer, specifying which
information is required; the second argument is a pointer to a variable into
-which the information is placed. The following information is available:
+which the information is placed. The returned value is zero on success, or the
+negative error code PCRE_ERROR_BADOPTION if the value in the first argument is
+not recognized. The following information is available:
.sp
PCRE_CONFIG_UTF8
.sp
The output is an integer that is set to one if UTF-8 support is available;
-otherwise it is set to zero.
+otherwise it is set to zero. If this option is given to the 16-bit version of
+this function, \fBpcre16_config()\fP, the result is PCRE_ERROR_BADOPTION.
+.sp
+ PCRE_CONFIG_UTF16
+.sp
+The output is an integer that is set to one if UTF-16 support is available;
+otherwise it is set to zero. This value should normally be given to the 16-bit
+version of this function, \fBpcre16_config()\fP. If it is given to the 8-bit
+version of this function, the result is PCRE_ERROR_BADOPTION.
.sp
PCRE_CONFIG_UNICODE_PROPERTIES
.sp
The output is an integer that is set to one if support for Unicode character
properties is available; otherwise it is set to zero.
.sp
+ PCRE_CONFIG_JIT
+.sp
+The output is an integer that is set to one if support for just-in-time
+compiling is available; otherwise it is set to zero.
+.sp
+ PCRE_CONFIG_JITTARGET
+.sp
+The output is a pointer to a zero-terminated "const char *" string. If JIT
+support is available, the string contains the name of the architecture for
+which the JIT compiler is configured, for example "x86 32bit (little endian +
+unaligned)". If JIT support is not available, the result is NULL.
+.sp
PCRE_CONFIG_NEWLINE
.sp
The output is an integer whose value specifies the default character sequence
@@ -343,10 +438,12 @@
PCRE_CONFIG_LINK_SIZE
.sp
The output is an integer that contains the number of bytes used for internal
-linkage in compiled regular expressions. The value is 2, 3, or 4. Larger values
-allow larger regular expressions to be compiled, at the expense of slower
-matching. The default value of 2 is sufficient for all but the most massive
-patterns, since it allows the compiled pattern to be up to 64K in size.
+linkage in compiled regular expressions. For the 8-bit library, the value can
+be 2, 3, or 4. For the 16-bit library, the value is either 2 or 4 and is still
+a number of bytes. The default value of 2 is sufficient for all but the most
+massive patterns, since it allows the compiled pattern to be up to 64K in size.
+Larger values allow larger regular expressions to be compiled, at the expense
+of slower matching.
.sp
PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
.sp
@@ -429,23 +526,23 @@
the pattern, the contents of the \fIoptions\fP argument specifies their
settings at the start of compilation and execution. The PCRE_ANCHORED,
PCRE_BSR_\fIxxx\fP, PCRE_NEWLINE_\fIxxx\fP, PCRE_NO_UTF8_CHECK, and
-PCRE_NO_START_OPT options can be set at the time of matching as well as at
+PCRE_NO_START_OPTIMIZE options can be set at the time of matching as well as at
compile time.
.P
If \fIerrptr\fP is NULL, \fBpcre_compile()\fP returns NULL immediately.
Otherwise, if compilation of a pattern fails, \fBpcre_compile()\fP returns
NULL, and sets the variable pointed to by \fIerrptr\fP to point to a textual
error message. This is a static string that is part of the library. You must
-not try to free it. The offset from the start of the pattern to the byte that
-was being processed when the error was discovered is placed in the variable
-pointed to by \fIerroffset\fP, which must not be NULL. If it is, an immediate
-error is given. Some errors are not detected until checks are carried out when
-the whole pattern has been scanned; in this case the offset is set to the end
-of the pattern.
-.P
-Note that the offset is in bytes, not characters, even in UTF-8 mode. It may
-point into the middle of a UTF-8 character (for example, when
-PCRE_ERROR_BADUTF8 is returned for an invalid UTF-8 string).
+not try to free it. Normally, the offset from the start of the pattern to the
+byte that was being processed when the error was discovered is placed in the
+variable pointed to by \fIerroffset\fP, which must not be NULL (if it is, an
+immediate error is given). However, for an invalid UTF-8 string, the offset is
+that of the first byte of the failing character.
+.P
+Some errors are not detected until the whole pattern has been scanned; in these
+cases, the offset passed back is the length of the pattern. Note that the
+offset is in bytes, not characters, even in UTF-8 mode. It may sometimes point
+into the middle of a UTF-8 character.
.P
If \fBpcre_compile2()\fP is used instead of \fBpcre_compile()\fP, and the
\fIerrorcodeptr\fP argument is not NULL, a non-zero error code number is
@@ -545,16 +642,16 @@
.sp
PCRE_EXTENDED
.sp
-If this bit is set, whitespace data characters in the pattern are totally
-ignored except when escaped or inside a character class. Whitespace does not
+If this bit is set, white space data characters in the pattern are totally
+ignored except when escaped or inside a character class. White space does not
include the VT character (code 11). In addition, characters between an
unescaped # outside a character class and the next newline, inclusive, are also
ignored. This is equivalent to Perl's /x option, and it can be changed within a
pattern by a (?x) option setting.
.P
-Which characters are interpreted as newlines
-is controlled by the options passed to \fBpcre_compile()\fP or by a special
-sequence at the start of the pattern, as described in the section entitled
+Which characters are interpreted as newlines is controlled by the options
+passed to \fBpcre_compile()\fP or by a special sequence at the start of the
+pattern, as described in the section entitled
.\" HTML
.\"
"Newline conventions"
@@ -564,7 +661,7 @@
happen to represent a newline do not count.
.P
This option makes it possible to include comments inside complicated patterns.
-Note, however, that this applies only to data characters. Whitespace characters
+Note, however, that this applies only to data characters. White space characters
may never appear within special character sequences in a pattern, for example
within the sequence (?( that introduces a conditional subpattern.
.sp
@@ -599,6 +696,20 @@
string (by default this causes the current matching alternative to fail). A
pattern such as (\e1)(a) succeeds when this option is set (assuming it can find
an "a" in the subject), whereas it fails by default, for Perl compatibility.
+.P
+(3) \eU matches an upper case "U" character; by default \eU causes a compile
+time error (Perl uses \eU to upper case subsequent characters).
+.P
+(4) \eu matches a lower case "u" character unless it is followed by four
+hexadecimal digits, in which case the hexadecimal number defines the code point
+to match. By default, \eu causes a compile time error (Perl uses it to upper
+case the following character).
+.P
+(5) \ex matches a lower case "x" character unless it is followed by two
+hexadecimal digits, in which case the hexadecimal number defines the code point
+to match. By default, as in Perl, a hexadecimal number is always expected after
+\ex, but it may have zero, one, or two digits (so, for example, \exz matches a
+binary zero character followed by z).
.sp
PCRE_MULTILINE
.sp
@@ -630,9 +741,9 @@
preceding sequences should be recognized. Setting PCRE_NEWLINE_ANY specifies
that any Unicode newline sequence should be recognized. The Unicode newline
sequences are the three just mentioned, plus the single characters VT (vertical
-tab, U+000B), FF (formfeed, U+000C), NEL (next line, U+0085), LS (line
-separator, U+2028), and PS (paragraph separator, U+2029). The last two are
-recognized only in UTF-8 mode.
+tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line
+separator, U+2028), and PS (paragraph separator, U+2029). For the 8-bit
+library, the last two are recognized only in UTF-8 mode.
.P
The newline setting in the options word uses three bits that are treated
as a number, giving eight possibilities. Currently only six are used (default
@@ -642,7 +753,7 @@
other combinations may yield unused numbers and cause an error.
.P
The only time that a line break in a pattern is specially recognized when
-compiling is when PCRE_EXTENDED is set. CR and LF are whitespace characters,
+compiling is when PCRE_EXTENDED is set. CR and LF are white space characters,
and so are ignored in this mode. Also, an unescaped # outside a character class
indicates a comment that lasts until after the next line break sequence. In
other circumstances, line break sequences in patterns are treated as literal
@@ -697,39 +808,34 @@
PCRE_UTF8
.sp
This option causes PCRE to regard both the pattern and the subject as strings
-of UTF-8 characters instead of single-byte character strings. However, it is
-available only when PCRE is built to include UTF-8 support. If not, the use
-of this option provokes an error. Details of how this option changes the
-behaviour of PCRE are given in the
-.\" HTML
-.\"
-section on UTF-8 support
-.\"
-in the main
+of UTF-8 characters instead of single-byte strings. However, it is available
+only when PCRE is built to include UTF support. If not, the use of this option
+provokes an error. Details of how this option changes the behaviour of PCRE are
+given in the
.\" HREF
-\fBpcre\fP
+\fBpcreunicode\fP
.\"
page.
.sp
PCRE_NO_UTF8_CHECK
.sp
-When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is
-automatically checked. There is a discussion about the
-.\" HTML
+When PCRE_UTF8 is set, the validity of the pattern as a UTF-8
+string is automatically checked. There is a discussion about the
+.\" HTML
.\"
validity of UTF-8 strings
.\"
-in the main
+in the
.\" HREF
-\fBpcre\fP
+\fBpcreunicode\fP
.\"
-page. If an invalid UTF-8 sequence of bytes is found, \fBpcre_compile()\fP
-returns an error. If you already know that your pattern is valid, and you want
-to skip this check for performance reasons, you can set the PCRE_NO_UTF8_CHECK
-option. When it is set, the effect of passing an invalid UTF-8 string as a
-pattern is undefined. It may cause your program to crash. Note that this option
-can also be passed to \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP, to suppress
-the UTF-8 validity checking of subject strings.
+page. If an invalid UTF-8 sequence is found, \fBpcre_compile()\fP returns an
+error. If you already know that your pattern is valid, and you want to skip
+this check for performance reasons, you can set the PCRE_NO_UTF8_CHECK option.
+When it is set, the effect of passing an invalid UTF-8 string as a pattern is
+undefined. It may cause your program to crash. Note that this option can also
+be passed to \fBpcre_exec()\fP and \fBpcre_dfa_exec()\fP, to suppress the
+validity checking of subject strings.
.
.
.SH "COMPILATION ERROR CODES"
@@ -737,8 +843,9 @@
.sp
The following table lists the error codes than may be returned by
\fBpcre_compile2()\fP, along with the error messages that may be returned by
-both compiling functions. As PCRE has developed, some error codes have fallen
-out of use. To avoid confusion, they have not been re-used.
+both compiling functions. Note that error messages are always 8-bit ASCII
+strings, even in 16-bit mode. As PCRE has developed, some error codes have
+fallen out of use. To avoid confusion, they have not been re-used.
.sp
0 no error
1 \e at end of pattern
@@ -772,26 +879,26 @@
29 (?R or (?[+-]digits must be followed by )
30 unknown POSIX class name
31 POSIX collating elements are not supported
- 32 this version of PCRE is not compiled with PCRE_UTF8 support
+ 32 this version of PCRE is compiled without UTF support
33 [this code is not in use]
34 character value in \ex{...} sequence is too large
35 invalid condition (?(0)
36 \eC not allowed in lookbehind assertion
- 37 PCRE does not support \eL, \el, \eN, \eU, or \eu
+ 37 PCRE does not support \eL, \el, \eN{name}, \eU, or \eu
38 number after (?C is > 255
39 closing ) for (?C expected
40 recursive call could loop indefinitely
41 unrecognized character after (?P
42 syntax error in subpattern name (missing terminator)
43 two named subpatterns have the same name
- 44 invalid UTF-8 string
+ 44 invalid UTF-8 string (specifically UTF-8)
45 support for \eP, \ep, and \eX has not been compiled
46 malformed \eP or \ep sequence
47 unknown property name after \eP or \ep
48 subpattern name is too long (maximum 32 characters)
49 too many named subpatterns (maximum 10000)
50 [this code is not in use]
- 51 octal value is greater than \e377 (not in UTF-8 mode)
+ 51 octal value is greater than \e377 in 8-bit non-UTF-8 mode
52 internal error: overran compiling workspace
53 internal error: previously-checked referenced subpattern
not found
@@ -810,12 +917,23 @@
65 different names for subpatterns of the same number are
not allowed
66 (*MARK) must have an argument
- 67 this version of PCRE is not compiled with PCRE_UCP support
+ 67 this version of PCRE is not compiled with Unicode property
+ support
+ 68 \ec must be followed by an ASCII character
+ 69 \ek is not followed by a braced, angle-bracketed, or quoted name
+ 70 internal error: unknown opcode in find_fixedlength()
+ 71 \eN is not supported in a class
+ 72 too many forward references
+ 73 disallowed Unicode code point (>= 0xd800 && <= 0xdfff)
+ 74 invalid UTF-16 string (specifically UTF-16)
+ 75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
+ 76 character value in \eu.... sequence is too large
.sp
The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may
be used if the limits were changed when PCRE was built.
.
.
+.\" HTML
.SH "STUDYING A PATTERN"
.rs
.sp
@@ -846,8 +964,29 @@
wants to pass any of the other fields to \fBpcre_exec()\fP or
\fBpcre_dfa_exec()\fP, it must set up its own \fBpcre_extra\fP block.
.P
-The second argument of \fBpcre_study()\fP contains option bits. At present, no
-options are defined, and this argument should always be zero.
+The second argument of \fBpcre_study()\fP contains option bits. There are three
+options:
+.sp
+ PCRE_STUDY_JIT_COMPILE
+ PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
+ PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
+.sp
+If any of these are set, and the just-in-time compiler is available, the
+pattern is further compiled into machine code that executes much faster than
+the \fBpcre_exec()\fP interpretive matching function. If the just-in-time
+compiler is not available, these options are ignored. All other bits in the
+\fIoptions\fP argument must be zero.
+.P
+JIT compilation is a heavyweight optimization. It can take some time for
+patterns to be analyzed, and for one-off matches and simple patterns the
+benefit of faster execution might be offset by a much slower study time.
+Not all patterns can be optimized by the JIT compiler. For those that cannot be
+handled, matching automatically falls back to the \fBpcre_exec()\fP
+interpreter. For more details, see the
+.\" HREF
+\fBpcrejit\fP
+.\"
+documentation.
.P
The third argument for \fBpcre_study()\fP is a pointer for an error message. If
studying succeeds (even if no data is returned), the variable it points to is
@@ -856,13 +995,29 @@
should test the error pointer for NULL after calling \fBpcre_study()\fP, to be
sure that it has run successfully.
.P
-This is a typical call to \fBpcre_study\fP():
+When you are finished with a pattern, you can free the memory used for the
+study data by calling \fBpcre_free_study()\fP. This function was added to the
+API for release 8.20. For earlier versions, the memory could be freed with
+\fBpcre_free()\fP, just like the pattern itself. This will still work in cases
+where JIT optimization is not used, but it is advisable to change to the new
+function when convenient.
+.P
+This is a typical way in which \fBpcre_study\fP() is used (except that in a
+real application there should be tests for errors):
.sp
- pcre_extra *pe;
- pe = pcre_study(
+ int rc;
+ pcre *re;
+ pcre_extra *sd;
+ re = pcre_compile("pattern", 0, &error, &erroroffset, NULL);
+ sd = pcre_study(
re, /* result of pcre_compile() */
- 0, /* no options exist */
+ 0, /* no options */
&error); /* set to NULL or points to a message */
+ rc = pcre_exec( /* see below for details of pcre_exec() options */
+ re, sd, "subject", 7, 0, 0, ovector, 30);
+ ...
+ pcre_free_study(sd);
+ pcre_free(re);
.sp
Studying a pattern does two things: first, a lower bound for the length of
subject string that is needed to match the pattern is computed. This does not
@@ -875,13 +1030,15 @@
Studying a pattern is also useful for non-anchored patterns that do not have a
single fixed starting character. A bitmap of possible starting bytes is
created. This speeds up finding a position in the subject at which to start
-matching.
+matching. (In 16-bit mode, the bitmap is used for 16-bit values less than 256.)
.P
-The two optimizations just described can be disabled by setting the
-PCRE_NO_START_OPTIMIZE option when calling \fBpcre_exec()\fP or
-\fBpcre_dfa_exec()\fP. You might want to do this if your pattern contains
-callouts or (*MARK), and you want to make use of these facilities in cases
-where matching fails. See the discussion of PCRE_NO_START_OPTIMIZE
+These two optimizations apply to both \fBpcre_exec()\fP and
+\fBpcre_dfa_exec()\fP, and the information is also used by the JIT compiler.
+The optimizations can be disabled by setting the PCRE_NO_START_OPTIMIZE option
+when calling \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP, but if this is done,
+JIT execution is also disabled. You might want to do this if your pattern
+contains callouts or (*MARK) and you want to make use of these facilities in
+cases where matching fails. See the discussion of PCRE_NO_START_OPTIMIZE
.\" HTML
.\"
below.
@@ -894,14 +1051,15 @@
.sp
PCRE handles caseless matching, and determines whether characters are letters,
digits, or whatever, by reference to a set of tables, indexed by character
-value. When running in UTF-8 mode, this applies only to characters with codes
-less than 128. By default, higher-valued codes never match escapes such as \ew
-or \ed, but they can be tested with \ep if PCRE is built with Unicode character
-property support. Alternatively, the PCRE_UCP option can be set at compile
-time; this causes \ew and friends to use Unicode property support instead of
-built-in tables. The use of locales with Unicode is discouraged. If you are
-handling characters with codes greater than 128, you should either use UTF-8
-and Unicode, or use locales, but not try to mix the two.
+value. When running in UTF-8 mode, this applies only to characters
+with codes less than 128. By default, higher-valued codes never match escapes
+such as \ew or \ed, but they can be tested with \ep if PCRE is built with
+Unicode character property support. Alternatively, the PCRE_UCP option can be
+set at compile time; this causes \ew and friends to use Unicode property
+support instead of built-in tables. The use of locales with Unicode is
+discouraged. If you are handling characters with codes greater than 128, you
+should either use UTF-8 and Unicode, or use locales, but not try to mix the
+two.
.P
PCRE contains an internal set of tables that are used when the final argument
of \fBpcre_compile()\fP is NULL. These are sufficient for many applications.
@@ -946,6 +1104,7 @@
below in the section on matching a pattern.
.
.
+.\" HTML
.SH "INFORMATION ABOUT A PATTERN"
.rs
.sp
@@ -954,8 +1113,8 @@
.B int \fIwhat\fP, void *\fIwhere\fP);
.PP
The \fBpcre_fullinfo()\fP function returns information about a compiled
-pattern. It replaces the obsolete \fBpcre_info()\fP function, which is
-nevertheless retained for backwards compability (and is documented below).
+pattern. It replaces the \fBpcre_info()\fP function, which was removed from the
+library at version 8.30, after more than 10 years of obsolescence.
.P
The first argument for \fBpcre_fullinfo()\fP is a pointer to the compiled
pattern. The second argument is the result of \fBpcre_study()\fP, or NULL if
@@ -964,20 +1123,24 @@
to receive the data. The yield of the function is zero for success, or one of
the following negative numbers:
.sp
- PCRE_ERROR_NULL the argument \fIcode\fP was NULL
- the argument \fIwhere\fP was NULL
- PCRE_ERROR_BADMAGIC the "magic number" was not found
- PCRE_ERROR_BADOPTION the value of \fIwhat\fP was invalid
+ PCRE_ERROR_NULL the argument \fIcode\fP was NULL
+ the argument \fIwhere\fP was NULL
+ PCRE_ERROR_BADMAGIC the "magic number" was not found
+ PCRE_ERROR_BADENDIANNESS the pattern was compiled with different
+ endianness
+ PCRE_ERROR_BADOPTION the value of \fIwhat\fP was invalid
.sp
The "magic number" is placed at the start of each compiled pattern as an simple
-check against passing an arbitrary memory pointer. Here is a typical call of
-\fBpcre_fullinfo()\fP, to obtain the length of the compiled pattern:
+check against passing an arbitrary memory pointer. The endianness error can
+occur if a compiled pattern is saved and reloaded on a different host. Here is
+a typical call of \fBpcre_fullinfo()\fP, to obtain the length of the compiled
+pattern:
.sp
int rc;
size_t length;
rc = pcre_fullinfo(
re, /* result of pcre_compile() */
- pe, /* result of pcre_study(), or NULL */
+ sd, /* result of pcre_study(), or NULL */
PCRE_INFO_SIZE, /* what is required */
&length); /* where to put the data */
.sp
@@ -1005,13 +1168,17 @@
.sp
PCRE_INFO_FIRSTBYTE
.sp
-Return information about the first byte of any matched string, for a
-non-anchored pattern. The fourth argument should point to an \fBint\fP
-variable. (This option used to be called PCRE_INFO_FIRSTCHAR; the old name is
-still recognized for backwards compatibility.)
+Return information about the first data unit of any matched string, for a
+non-anchored pattern. (The name of this option refers to the 8-bit library,
+where data units are bytes.) The fourth argument should point to an \fBint\fP
+variable.
.P
-If there is a fixed first byte, for example, from a pattern such as
-(cat|cow|coyote), its value is returned. Otherwise, if either
+If there is a fixed first value, for example, the letter "c" from a pattern
+such as (cat|cow|coyote), its value is returned. In the 8-bit library, the
+value is always less than 256; in the 16-bit library the value can be up to
+0xffff.
+.P
+If there is no fixed first value, and if either
.sp
(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch
starts with "^", or
@@ -1026,7 +1193,7 @@
PCRE_INFO_FIRSTTABLE
.sp
If the pattern was studied, and this resulted in the construction of a 256-bit
-table indicating a fixed set of bytes for the first byte in any matching
+table indicating a fixed set of values for the first data unit in any matching
string, a pointer to the table is returned. Otherwise NULL is returned. The
fourth argument should point to an \fBunsigned char *\fP variable.
.sp
@@ -1042,22 +1209,47 @@
0. The fourth argument should point to an \fBint\fP variable. (?J) and
(?-J) set and unset the local PCRE_DUPNAMES option, respectively.
.sp
+ PCRE_INFO_JIT
+.sp
+Return 1 if the pattern was studied with one of the JIT options, and
+just-in-time compiling was successful. The fourth argument should point to an
+\fBint\fP variable. A return value of 0 means that JIT support is not available
+in this version of PCRE, or that the pattern was not studied with a JIT option,
+or that the JIT compiler could not handle this particular pattern. See the
+.\" HREF
+\fBpcrejit\fP
+.\"
+documentation for details of what can and cannot be handled.
+.sp
+ PCRE_INFO_JITSIZE
+.sp
+If the pattern was successfully studied with a JIT option, return the size of
+the JIT compiled code, otherwise return zero. The fourth argument should point
+to a \fBsize_t\fP variable.
+.sp
PCRE_INFO_LASTLITERAL
.sp
-Return the value of the rightmost literal byte that must exist in any matched
-string, other than at its start, if such a byte has been recorded. The fourth
-argument should point to an \fBint\fP variable. If there is no such byte, -1 is
-returned. For anchored patterns, a last literal byte is recorded only if it
-follows something of variable length. For example, for the pattern
+Return the value of the rightmost literal data unit that must exist in any
+matched string, other than at its start, if such a value has been recorded. The
+fourth argument should point to an \fBint\fP variable. If there is no such
+value, -1 is returned. For anchored patterns, a last literal value is recorded
+only if it follows something of variable length. For example, for the pattern
/^a\ed+z\ed+/ the returned value is "z", but for /^a\edz\ed/ the returned value
is -1.
.sp
+ PCRE_INFO_MAXLOOKBEHIND
+.sp
+Return the number of characters (NB not bytes) in the longest lookbehind
+assertion in the pattern. Note that the simple assertions \eb and \eB require a
+one-character lookbehind. This information is useful when doing multi-segment
+matching using the partial matching facilities.
+.sp
PCRE_INFO_MINLENGTH
.sp
If the pattern was studied and a minimum length for matching subject strings
was computed, its value is returned. Otherwise the returned value is -1. The
-value is a number of characters, not bytes (this may be relevant in UTF-8
-mode). The fourth argument should point to an \fBint\fP variable. A
+value is a number of characters, which in UTF-8 mode may be different from the
+number of bytes. The fourth argument should point to an \fBint\fP variable. A
non-negative value is a lower bound to the length of any matching string. There
may not be any strings of that length that do actually match, but every string
that does match is at least that long.
@@ -1080,9 +1272,11 @@
the number of entries, and PCRE_INFO_NAMEENTRYSIZE gives the size of each
entry; both of these return an \fBint\fP value. The entry size depends on the
length of the longest name. PCRE_INFO_NAMETABLE returns a pointer to the first
-entry of the table (a pointer to \fBchar\fP). The first two bytes of each entry
-are the number of the capturing parenthesis, most significant byte first. The
-rest of the entry is the corresponding name, zero terminated.
+entry of the table. This is a pointer to \fBchar\fP in the 8-bit library, where
+the first two bytes of each entry are the number of the capturing parenthesis,
+most significant byte first. In the 16-bit library, the pointer points to
+16-bit data units, the first of which contains the parenthesis number. The rest
+of the entry is the corresponding name, zero terminated.
.P
The names are in alphabetical order. Duplicate names may appear if (?| is used
to create multiple groups with the same number, as described in the
@@ -1101,8 +1295,8 @@
necessarily the case because later subpatterns may have lower numbers.
.P
As a simple example of the name/number table, consider the following pattern
-(assume PCRE_EXTENDED is set, so white space - including newlines - is
-ignored):
+after compilation by the 8-bit library (assume PCRE_EXTENDED is set, so white
+space - including newlines - is ignored):
.sp
.\" JOIN
(? (?(\ed\ed)?\ed\ed) -
@@ -1157,43 +1351,32 @@
.sp
PCRE_INFO_SIZE
.sp
-Return the size of the compiled pattern, that is, the value that was passed as
-the argument to \fBpcre_malloc()\fP when PCRE was getting memory in which to
-place the compiled data. The fourth argument should point to a \fBsize_t\fP
-variable.
+Return the size of the compiled pattern in bytes (for both libraries). The
+fourth argument should point to a \fBsize_t\fP variable. This value does not
+include the size of the \fBpcre\fP structure that is returned by
+\fBpcre_compile()\fP. The value that is passed as the argument to
+\fBpcre_malloc()\fP when \fBpcre_compile()\fP is getting memory in which to
+place the compiled data is the value returned by this option plus the size of
+the \fBpcre\fP structure. Studying a compiled pattern, with or without JIT,
+does not alter the value returned by this option.
.sp
PCRE_INFO_STUDYSIZE
.sp
-Return the size of the data block pointed to by the \fIstudy_data\fP field in
-a \fBpcre_extra\fP block. That is, it is the value that was passed to
-\fBpcre_malloc()\fP when PCRE was getting memory into which to place the data
-created by \fBpcre_study()\fP. If \fBpcre_extra\fP is NULL, or there is no
+Return the size in bytes of the data block pointed to by the \fIstudy_data\fP
+field in a \fBpcre_extra\fP block. If \fBpcre_extra\fP is NULL, or there is no
study data, zero is returned. The fourth argument should point to a
-\fBsize_t\fP variable.
-.
-.
-.SH "OBSOLETE INFO FUNCTION"
-.rs
-.sp
-.B int pcre_info(const pcre *\fIcode\fP, int *\fIoptptr\fP, int
-.B *\fIfirstcharptr\fP);
-.PP
-The \fBpcre_info()\fP function is now obsolete because its interface is too
-restrictive to return all the available data about a compiled pattern. New
-programs should use \fBpcre_fullinfo()\fP instead. The yield of
-\fBpcre_info()\fP is the number of capturing subpatterns, or one of the
-following negative numbers:
-.sp
- PCRE_ERROR_NULL the argument \fIcode\fP was NULL
- PCRE_ERROR_BADMAGIC the "magic number" was not found
-.sp
-If the \fIoptptr\fP argument is not NULL, a copy of the options with which the
-pattern was compiled is placed in the integer it points to (see
-PCRE_INFO_OPTIONS above).
-.P
-If the pattern is not anchored and the \fIfirstcharptr\fP argument is not NULL,
-it is used to pass back information about the first character of any matched
-string (see PCRE_INFO_FIRSTBYTE above).
+\fBsize_t\fP variable. The \fIstudy_data\fP field is set by \fBpcre_study()\fP
+to record information that will speed up matching (see the section entitled
+.\" HTML
+.\"
+"Studying a pattern"
+.\"
+above). The format of the \fIstudy_data\fP block is private, but its length
+is made available via this option so that it can be saved and restored (see the
+.\" HREF
+\fBpcreprecompile\fP
+.\"
+documentation for details).
.
.
.SH "REFERENCE COUNTS"
@@ -1231,9 +1414,13 @@
The function \fBpcre_exec()\fP is called to match a subject string against a
compiled pattern, which is passed in the \fIcode\fP argument. If the
pattern was studied, the result of the study should be passed in the
-\fIextra\fP argument. This function is the main matching facility of the
-library, and it operates in a Perl-like manner. For specialist use there is
-also an alternative matching function, which is described
+\fIextra\fP argument. You can call \fBpcre_exec()\fP with the same \fIcode\fP
+and \fIextra\fP arguments as many times as you like, in order to match
+different subject strings with the same pattern.
+.P
+This function is the main matching facility of the library, and it operates in
+a Perl-like manner. For specialist use there is also an alternative matching
+function, which is described
.\" HTML
.\"
below
@@ -1264,6 +1451,7 @@
ovector, /* vector of integers for substring information */
30); /* number of elements (NOT size in bytes) */
.
+.
.\" HTML
.SS "Extra data for \fBpcre_exec()\fR"
.rs
@@ -1276,38 +1464,50 @@
.sp
unsigned long int \fIflags\fP;
void *\fIstudy_data\fP;
+ void *\fIexecutable_jit\fP;
unsigned long int \fImatch_limit\fP;
unsigned long int \fImatch_limit_recursion\fP;
void *\fIcallout_data\fP;
const unsigned char *\fItables\fP;
unsigned char **\fImark\fP;
.sp
-The \fIflags\fP field is a bitmap that specifies which of the other fields
-are set. The flag bits are:
+In the 16-bit version of this structure, the \fImark\fP field has type
+"PCRE_UCHAR16 **".
+.P
+The \fIflags\fP field is used to specify which of the other fields are set. The
+flag bits are:
.sp
- PCRE_EXTRA_STUDY_DATA
+ PCRE_EXTRA_CALLOUT_DATA
+ PCRE_EXTRA_EXECUTABLE_JIT
+ PCRE_EXTRA_MARK
PCRE_EXTRA_MATCH_LIMIT
PCRE_EXTRA_MATCH_LIMIT_RECURSION
- PCRE_EXTRA_CALLOUT_DATA
+ PCRE_EXTRA_STUDY_DATA
PCRE_EXTRA_TABLES
- PCRE_EXTRA_MARK
.sp
-Other flag bits should be set to zero. The \fIstudy_data\fP field is set in the
-\fBpcre_extra\fP block that is returned by \fBpcre_study()\fP, together with
-the appropriate flag bit. You should not set this yourself, but you may add to
-the block by setting the other fields and their corresponding flag bits.
+Other flag bits should be set to zero. The \fIstudy_data\fP field and sometimes
+the \fIexecutable_jit\fP field are set in the \fBpcre_extra\fP block that is
+returned by \fBpcre_study()\fP, together with the appropriate flag bits. You
+should not set these yourself, but you may add to the block by setting other
+fields and their corresponding flag bits.
.P
The \fImatch_limit\fP field provides a means of preventing PCRE from using up a
vast amount of resources when running patterns that are not going to match,
but which have a very large number of possibilities in their search trees. The
classic example is a pattern that uses nested unlimited repeats.
.P
-Internally, PCRE uses a function called \fBmatch()\fP which it calls repeatedly
-(sometimes recursively). The limit set by \fImatch_limit\fP is imposed on the
-number of times this function is called during a match, which has the effect of
-limiting the amount of backtracking that can take place. For patterns that are
-not anchored, the count restarts from zero for each position in the subject
-string.
+Internally, \fBpcre_exec()\fP uses a function called \fBmatch()\fP, which it
+calls repeatedly (sometimes recursively). The limit set by \fImatch_limit\fP is
+imposed on the number of times this function is called during a match, which
+has the effect of limiting the amount of backtracking that can take place. For
+patterns that are not anchored, the count restarts from zero for each position
+in the subject string.
+.P
+When \fBpcre_exec()\fP is called with a pattern that was successfully studied
+with a JIT option, the way that the matching is executed is entirely different.
+However, there is still the possibility of runaway matching that goes on for a
+very long time, and so the \fImatch_limit\fP value is also used in this case
+(but in a different way) to limit how long the matching can continue.
.P
The default value for the limit can be set when PCRE is built; the default
default is 10 million, which handles all but the most extreme cases. You can
@@ -1322,9 +1522,10 @@
total number of calls, because not all calls to \fBmatch()\fP are recursive.
This limit is of use only if it is set smaller than \fImatch_limit\fP.
.P
-Limiting the recursion depth limits the amount of stack that can be used, or,
-when PCRE has been compiled to use memory on the heap instead of the stack, the
-amount of heap memory that can be used.
+Limiting the recursion depth limits the amount of machine stack that can be
+used, or, when PCRE has been compiled to use memory on the heap instead of the
+stack, the amount of heap memory that can be used. This limit is not relevant,
+and is ignored, when matching is done using JIT compiled code.
.P
The default value for \fImatch_limit_recursion\fP can be set when PCRE is
built; the default default is the same value as the default for
@@ -1355,13 +1556,13 @@
documentation for a discussion of saving compiled patterns for later use.
.P
If PCRE_EXTRA_MARK is set in the \fIflags\fP field, the \fImark\fP field must
-be set to point to a \fBchar *\fP variable. If the pattern contains any
+be set to point to a suitable variable. If the pattern contains any
backtracking control verbs such as (*MARK:NAME), and the execution ends up with
a name to pass back, a pointer to the name string (zero terminated) is placed
in the variable pointed to by the \fImark\fP field. The names are within the
compiled pattern; if you wish to retain such a name you must copy it before
freeing the memory of a compiled pattern. If there is no name to pass back, the
-variable pointed to by the \fImark\fP field set to NULL. For details of the
+variable pointed to by the \fImark\fP field is set to NULL. For details of the
backtracking control verbs, see the section entitled
.\" HTML
.\"
@@ -1381,8 +1582,15 @@
The unused bits of the \fIoptions\fP argument for \fBpcre_exec()\fP must be
zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_\fIxxx\fP,
PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART,
-PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_SOFT, and
-PCRE_PARTIAL_HARD.
+PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and
+PCRE_PARTIAL_SOFT.
+.P
+If the pattern was successfully studied with one of the just-in-time (JIT)
+compile options, the only supported options for JIT execution are
+PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY,
+PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an
+unsupported option is used, JIT execution is disabled and the normal
+interpretive code in \fBpcre_exec()\fP is run.
.sp
PCRE_ANCHORED
.sp
@@ -1501,7 +1709,8 @@
"no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK)
are considered at every possible starting position in the subject string. If
PCRE_NO_START_OPTIMIZE is set at compile time, it cannot be unset at matching
-time.
+time. The use of PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set,
+matching is always done using interpretively.
.P
Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation.
Consider the pattern
@@ -1534,22 +1743,29 @@
.sp
When PCRE_UTF8 is set at compile time, the validity of the subject as a UTF-8
string is automatically checked when \fBpcre_exec()\fP is subsequently called.
-The value of \fIstartoffset\fP is also checked to ensure that it points to the
-start of a UTF-8 character. There is a discussion about the validity of UTF-8
-strings in the
-.\" HTML
+The entire string is checked before any other processing takes place. The value
+of \fIstartoffset\fP is also checked to ensure that it points to the start of a
+UTF-8 character. There is a discussion about the
+.\" HTML
.\"
-section on UTF-8 support
+validity of UTF-8 strings
.\"
-in the main
+in the
.\" HREF
-\fBpcre\fP
+\fBpcreunicode\fP
.\"
-page. If an invalid UTF-8 sequence of bytes is found, \fBpcre_exec()\fP returns
-the error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is
-a truncated UTF-8 character at the end of the subject, PCRE_ERROR_SHORTUTF8. If
-\fIstartoffset\fP contains a value that does not point to the start of a UTF-8
-character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is
+page. If an invalid sequence of bytes is found, \fBpcre_exec()\fP returns the
+error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a
+truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In both
+cases, information about the precise nature of the error may also be returned
+(see the descriptions of these errors in the section entitled \fIError return
+values from\fP \fBpcre_exec()\fP
+.\" HTML
+.\"
+below).
+.\"
+If \fIstartoffset\fP contains a value that does not point to the start of a
+UTF-8 character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is
returned.
.P
If you already know that your subject is valid, and you want to skip these
@@ -1557,9 +1773,9 @@
calling \fBpcre_exec()\fP. You might want to do this for the second and
subsequent calls to \fBpcre_exec()\fP if you are making repeated calls to find
all the matches in a single subject string. However, you should be sure that
-the value of \fIstartoffset\fP points to the start of a UTF-8 character (or the
-end of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an
-invalid UTF-8 string as a subject or an invalid value of \fIstartoffset\fP is
+the value of \fIstartoffset\fP points to the start of a character (or the end
+of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an
+invalid string as a subject or an invalid value of \fIstartoffset\fP is
undefined. Your program may crash.
.sp
PCRE_PARTIAL_HARD
@@ -1594,7 +1810,7 @@
.rs
.sp
The subject string is passed to \fBpcre_exec()\fP as a pointer in
-\fIsubject\fP, a length (in bytes) in \fIlength\fP, and a starting byte offset
+\fIsubject\fP, a length in bytes in \fIlength\fP, and a starting byte offset
in \fIstartoffset\fP. If this is negative or greater than the length of the
subject, \fBpcre_exec()\fP returns PCRE_ERROR_BADOFFSET. When the starting
offset is zero, the search for a match starts at the beginning of the subject,
@@ -1682,12 +1898,27 @@
.P
If the vector is too small to hold all the captured substring offsets, it is
used as far as possible (up to two-thirds of its length), and the function
-returns a value of zero. If the substring offsets are not of interest,
-\fBpcre_exec()\fP may be called with \fIovector\fP passed as NULL and
-\fIovecsize\fP as zero. However, if the pattern contains back references and
-the \fIovector\fP is not big enough to remember the related substrings, PCRE
-has to get additional memory for use during matching. Thus it is usually
-advisable to supply an \fIovector\fP.
+returns a value of zero. If neither the actual string matched nor any captured
+substrings are of interest, \fBpcre_exec()\fP may be called with \fIovector\fP
+passed as NULL and \fIovecsize\fP as zero. However, if the pattern contains
+back references and the \fIovector\fP is not big enough to remember the related
+substrings, PCRE has to get additional memory for use during matching. Thus it
+is usually advisable to supply an \fIovector\fP of reasonable size.
+.P
+There are some cases where zero is returned (indicating vector overflow) when
+in fact the vector is exactly the right size for the final match. For example,
+consider the pattern
+.sp
+ (a)(?:(b)c|bd)
+.sp
+If a vector of 6 elements (allowing for only 1 captured substring) is given
+with subject string "abd", \fBpcre_exec()\fP will try to set the second
+captured string, thereby recording a vector overflow, before failing to match
+"c" and backing up to try the second alternative. The zero return, however,
+does correctly indicate that the maximum number of slots (namely 2) have been
+filled. In similar cases where there is temporary overflow, but the final
+number of used slots is actually less than the maximum, a non-zero value is
+returned.
.P
The \fBpcre_fullinfo()\fP function can be used to find out how many capturing
subpatterns there are in a compiled pattern. The smallest size for
@@ -1708,15 +1939,16 @@
number is 1, and the offsets for for the second and third capturing subpatterns
(assuming the vector is large enough, of course) are set to -1.
.P
-\fBNote\fP: Elements of \fIovector\fP that do not correspond to capturing
-parentheses in the pattern are never changed. That is, if a pattern contains
-\fIn\fP capturing parentheses, no more than \fIovector[0]\fP to
-\fIovector[2n+1]\fP are set by \fBpcre_exec()\fP. The other elements retain
-whatever values they previously had.
+\fBNote\fP: Elements in the first two-thirds of \fIovector\fP that do not
+correspond to capturing parentheses in the pattern are never changed. That is,
+if a pattern contains \fIn\fP capturing parentheses, no more than
+\fIovector[0]\fP to \fIovector[2n+1]\fP are set by \fBpcre_exec()\fP. The other
+elements (in the first two-thirds) retain whatever values they previously had.
.P
Some convenience functions are provided for extracting the captured substrings
as separate strings. These are described below.
.
+.
.\" HTML
.SS "Error return values from \fBpcre_exec()\fP"
.rs
@@ -1786,14 +2018,24 @@
.sp
PCRE_ERROR_BADUTF8 (-10)
.sp
-A string that contains an invalid UTF-8 byte sequence was passed as a subject.
-However, if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8
-character at the end of the subject, PCRE_ERROR_SHORTUTF8 is used instead.
+A string that contains an invalid UTF-8 byte sequence was passed as a subject,
+and the PCRE_NO_UTF8_CHECK option was not set. If the size of the output vector
+(\fIovecsize\fP) is at least 2, the byte offset to the start of the the invalid
+UTF-8 character is placed in the first element, and a reason code is placed in
+the second element. The reason codes are listed in the
+.\" HTML
+.\"
+following section.
+.\"
+For backward compatibility, if PCRE_PARTIAL_HARD is set and the problem is a
+truncated UTF-8 character at the end of the subject (reason codes 1 to 5),
+PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8.
.sp
PCRE_ERROR_BADUTF8_OFFSET (-11)
.sp
-The UTF-8 byte sequence that was passed as a subject was valid, but the value
-of \fIstartoffset\fP did not point to the beginning of a UTF-8 character or the
+The UTF-8 byte sequence that was passed as a subject was checked and found to
+be valid (the PCRE_NO_UTF8_CHECK option was not set), but the value of
+\fIstartoffset\fP did not point to the beginning of a UTF-8 character or the
end of the subject.
.sp
PCRE_ERROR_PARTIAL (-12)
@@ -1837,11 +2079,127 @@
.sp
PCRE_ERROR_SHORTUTF8 (-25)
.sp
-The subject string ended with an incomplete (truncated) UTF-8 character, and
-the PCRE_PARTIAL_HARD option was set. Without this option, PCRE_ERROR_BADUTF8
-is returned in this situation.
+This error is returned instead of PCRE_ERROR_BADUTF8 when the subject string
+ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD option is set.
+Information about the failure is returned as for PCRE_ERROR_BADUTF8. It is in
+fact sufficient to detect this case, but this special error code for
+PCRE_PARTIAL_HARD precedes the implementation of returned information; it is
+retained for backwards compatibility.
+.sp
+ PCRE_ERROR_RECURSELOOP (-26)
+.sp
+This error is returned when \fBpcre_exec()\fP detects a recursion loop within
+the pattern. Specifically, it means that either the whole pattern or a
+subpattern has been called recursively for the second time at the same position
+in the subject string. Some simple patterns that might do this are detected and
+faulted at compile time, but more complicated cases, in particular mutual
+recursions between two different subpatterns, cannot be detected until run
+time.
+.sp
+ PCRE_ERROR_JIT_STACKLIMIT (-27)
+.sp
+This error is returned when a pattern that was successfully studied using a
+JIT compile option is being matched, but the memory available for the
+just-in-time processing stack is not large enough. See the
+.\" HREF
+\fBpcrejit\fP
+.\"
+documentation for more details.
+.sp
+ PCRE_ERROR_BADMODE (-28)
+.sp
+This error is given if a pattern that was compiled by the 8-bit library is
+passed to a 16-bit library function, or vice versa.
+.sp
+ PCRE_ERROR_BADENDIANNESS (-29)
+.sp
+This error is given if a pattern that was compiled and saved is reloaded on a
+host with different endianness. The utility function
+\fBpcre_pattern_to_host_byte_order()\fP can be used to convert such a pattern
+so that it runs on the new host.
.P
-Error numbers -16 to -20 and -22 are not used by \fBpcre_exec()\fP.
+Error numbers -16 to -20, -22, and -30 are not used by \fBpcre_exec()\fP.
+.
+.
+.\" HTML
+.SS "Reason codes for invalid UTF-8 strings"
+.rs
+.sp
+This section applies only to the 8-bit library. The corresponding information
+for the 16-bit library is given in the
+.\" HREF
+\fBpcre16\fP
+.\"
+page.
+.P
+When \fBpcre_exec()\fP returns either PCRE_ERROR_BADUTF8 or
+PCRE_ERROR_SHORTUTF8, and the size of the output vector (\fIovecsize\fP) is at
+least 2, the offset of the start of the invalid UTF-8 character is placed in
+the first output vector element (\fIovector[0]\fP) and a reason code is placed
+in the second element (\fIovector[1]\fP). The reason codes are given names in
+the \fBpcre.h\fP header file:
+.sp
+ PCRE_UTF8_ERR1
+ PCRE_UTF8_ERR2
+ PCRE_UTF8_ERR3
+ PCRE_UTF8_ERR4
+ PCRE_UTF8_ERR5
+.sp
+The string ends with a truncated UTF-8 character; the code specifies how many
+bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 characters to be
+no longer than 4 bytes, the encoding scheme (originally defined by RFC 2279)
+allows for up to 6 bytes, and this is checked first; hence the possibility of
+4 or 5 missing bytes.
+.sp
+ PCRE_UTF8_ERR6
+ PCRE_UTF8_ERR7
+ PCRE_UTF8_ERR8
+ PCRE_UTF8_ERR9
+ PCRE_UTF8_ERR10
+.sp
+The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of the
+character do not have the binary value 0b10 (that is, either the most
+significant bit is 0, or the next bit is 1).
+.sp
+ PCRE_UTF8_ERR11
+ PCRE_UTF8_ERR12
+.sp
+A character that is valid by the RFC 2279 rules is either 5 or 6 bytes long;
+these code points are excluded by RFC 3629.
+.sp
+ PCRE_UTF8_ERR13
+.sp
+A 4-byte character has a value greater than 0x10fff; these code points are
+excluded by RFC 3629.
+.sp
+ PCRE_UTF8_ERR14
+.sp
+A 3-byte character has a value in the range 0xd800 to 0xdfff; this range of
+code points are reserved by RFC 3629 for use with UTF-16, and so are excluded
+from UTF-8.
+.sp
+ PCRE_UTF8_ERR15
+ PCRE_UTF8_ERR16
+ PCRE_UTF8_ERR17
+ PCRE_UTF8_ERR18
+ PCRE_UTF8_ERR19
+.sp
+A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes for a
+value that can be represented by fewer bytes, which is invalid. For example,
+the two bytes 0xc0, 0xae give the value 0x2e, whose correct coding uses just
+one byte.
+.sp
+ PCRE_UTF8_ERR20
+.sp
+The two most significant bits of the first byte of a character have the binary
+value 0b10 (that is, the most significant bit is 1 and the second is 0). Such a
+byte can only validly occur as the second or subsequent byte of a multi-byte
+character.
+.sp
+ PCRE_UTF8_ERR21
+.sp
+The first byte of a character has the value 0xfe or 0xff. These values can
+never occur in a valid UTF-8 string.
.
.
.SH "EXTRACTING CAPTURED SUBSTRINGS BY NUMBER"
@@ -2006,6 +2364,7 @@
numbers. For this reason, the use of different names for subpatterns of the
same number causes an error at compile time.
.
+.
.SH "DUPLICATE SUBPATTERN NAMES"
.rs
.sp
@@ -2039,7 +2398,11 @@
has run, they point to the first and last entries in the name-to-number table
for the given name. The function itself returns the length of each entry, or
PCRE_ERROR_NOSUBSTRING (-7) if there are none. The format of the table is
-described above in the section entitled \fIInformation about a pattern\fP.
+described above in the section entitled \fIInformation about a pattern\fP
+.\" HTML
+.\"
+above.
+.\"
Given all the relevant entries for the name, you can extract each of their
numbers, and hence the captured data, if any.
.
@@ -2066,6 +2429,32 @@
will yield PCRE_ERROR_NOMATCH.
.
.
+.SH "OBTAINING AN ESTIMATE OF STACK USAGE"
+.rs
+.sp
+Matching certain patterns using \fBpcre_exec()\fP can use a lot of process
+stack, which in certain environments can be rather limited in size. Some users
+find it helpful to have an estimate of the amount of stack that is used by
+\fBpcre_exec()\fP, to help them set recursion limits, as described in the
+.\" HREF
+\fBpcrestack\fP
+.\"
+documentation. The estimate that is output by \fBpcretest\fP when called with
+the \fB-m\fP and \fB-C\fP options is obtained by calling \fBpcre_exec\fP with
+the values NULL, NULL, NULL, -999, and -999 for its first five arguments.
+.P
+Normally, if its first argument is NULL, \fBpcre_exec()\fP immediately returns
+the negative error code PCRE_ERROR_NULL, but with this special combination of
+arguments, it returns instead a negative number whose absolute value is the
+approximate stack frame size in bytes. (A negative number is used so that it is
+clear that no match has happened.) The value is approximate because in some
+cases, recursive calls to \fBpcre_exec()\fP occur when there are one or two
+additional variables on the stack.
+.P
+If PCRE has been compiled to use the heap instead of the stack for recursion,
+the value returned is the size of each block that is obtained from the heap.
+.
+.
.\" HTML
.SH "MATCHING A PATTERN: THE ALTERNATIVE FUNCTION"
.rs
@@ -2169,6 +2558,7 @@
.\"
documentation.
.
+.
.SS "Successful returns from \fBpcre_dfa_exec()\fP"
.rs
.sp
@@ -2200,7 +2590,9 @@
The strings are returned in reverse order of length; that is, the longest
matching string is given first. If there were too many matches to fit into
\fIovector\fP, the yield of the function is zero, and the vector is filled with
-the longest matches.
+the longest matches. Unlike \fBpcre_exec()\fP, \fBpcre_dfa_exec()\fP can use
+the entire \fIovector\fP for returning matched strings.
+.
.
.SS "Error returns from \fBpcre_dfa_exec()\fP"
.rs
@@ -2229,8 +2621,9 @@
PCRE_ERROR_DFA_UMLIMIT (-18)
.sp
This return is given if \fBpcre_dfa_exec()\fP is called with an \fIextra\fP
-block that contains a setting of the \fImatch_limit\fP field. This is not
-supported (it is meaningless).
+block that contains a setting of the \fImatch_limit\fP or
+\fImatch_limit_recursion\fP fields. This is not supported (these fields are
+meaningless for DFA matching).
.sp
PCRE_ERROR_DFA_WSSIZE (-19)
.sp
@@ -2243,12 +2636,19 @@
recursively, using private vectors for \fIovector\fP and \fIworkspace\fP. This
error is given if the output vector is not large enough. This should be
extremely rare, as a vector of size 1000 is used.
+.sp
+ PCRE_ERROR_DFA_BADRESTART (-30)
+.sp
+When \fBpcre_dfa_exec()\fP is called with the \fBPCRE_DFA_RESTART\fP option,
+some plausibility checks are made on the contents of the workspace, which
+should contain data about the previous partial match. If any of these checks
+fail, this error is given.
.
.
.SH "SEE ALSO"
.rs
.sp
-\fBpcrebuild\fP(3), \fBpcrecallout\fP(3), \fBpcrecpp(3)\fP(3),
+\fBpcre16\fP(3), \fBpcrebuild\fP(3), \fBpcrecallout\fP(3), \fBpcrecpp(3)\fP(3),
\fBpcrematching\fP(3), \fBpcrepartial\fP(3), \fBpcreposix\fP(3),
\fBpcreprecompile\fP(3), \fBpcresample\fP(3), \fBpcrestack\fP(3).
.
@@ -2267,6 +2667,6 @@
.rs
.sp
.nf
-Last updated: 21 November 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 17 June 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcrebuild.3 pcre3-8.31/doc/pcrebuild.3
--- pcre3-8.12/doc/pcrebuild.3 2009-10-05 10:40:30.000000000 +0000
+++ pcre3-8.31/doc/pcrebuild.3 2012-05-26 14:21:10.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCREBUILD 3
+.TH PCREBUILD 3 "07 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.
@@ -32,49 +32,92 @@
exists as well, but as it specifies the default, it is not described.
.
.
+.SH "BUILDING 8-BIT and 16-BIT LIBRARIES"
+.rs
+.sp
+By default, a library called \fBlibpcre\fP is built, containing functions that
+take string arguments contained in vectors of bytes, either as single-byte
+characters, or interpreted as UTF-8 strings. You can also build a separate
+library, called \fBlibpcre16\fP, in which strings are contained in vectors of
+16-bit data units and interpreted either as single-unit characters or UTF-16
+strings, by adding
+.sp
+ --enable-pcre16
+.sp
+to the \fBconfigure\fP command. If you do not want the 8-bit library, add
+.sp
+ --disable-pcre8
+.sp
+as well. At least one of the two libraries must be built. Note that the C++ and
+POSIX wrappers are for the 8-bit library only, and that \fBpcregrep\fP is an
+8-bit program. None of these are built if you select only the 16-bit library.
+.
+.
+.SH "BUILDING SHARED AND STATIC LIBRARIES"
+.rs
+.sp
+The PCRE building process uses \fBlibtool\fP to build both shared and static
+Unix libraries by default. You can suppress one of these by adding one of
+.sp
+ --disable-shared
+ --disable-static
+.sp
+to the \fBconfigure\fP command, as required.
+.
+.
.SH "C++ SUPPORT"
.rs
.sp
-By default, the \fBconfigure\fP script will search for a C++ compiler and C++
-header files. If it finds them, it automatically builds the C++ wrapper library
-for PCRE. You can disable this by adding
+By default, if the 8-bit library is being built, the \fBconfigure\fP script
+will search for a C++ compiler and C++ header files. If it finds them, it
+automatically builds the C++ wrapper library (which supports only 8-bit
+strings). You can disable this by adding
.sp
--disable-cpp
.sp
to the \fBconfigure\fP command.
.
.
-.SH "UTF-8 SUPPORT"
+.SH "UTF-8 and UTF-16 SUPPORT"
.rs
.sp
-To build PCRE with support for UTF-8 Unicode character strings, add
+To build PCRE with support for UTF Unicode character strings, add
.sp
- --enable-utf8
+ --enable-utf
.sp
-to the \fBconfigure\fP command. Of itself, this does not make PCRE treat
-strings as UTF-8. As well as compiling PCRE with this option, you also have
-have to set the PCRE_UTF8 option when you call the \fBpcre_compile()\fP
-or \fBpcre_compile2()\fP functions.
+to the \fBconfigure\fP command. This setting applies to both libraries, adding
+support for UTF-8 to the 8-bit library and support for UTF-16 to the 16-bit
+library. There are no separate options for enabling UTF-8 and UTF-16
+independently because that would allow ridiculous settings such as requesting
+UTF-16 support while building only the 8-bit library. It is not possible to
+build one library with UTF support and the other without in the same
+configuration. (For backwards compatibility, --enable-utf8 is a synonym of
+--enable-utf.)
+.P
+Of itself, this setting does not make PCRE treat strings as UTF-8 or UTF-16. As
+well as compiling PCRE with this option, you also have have to set the
+PCRE_UTF8 or PCRE_UTF16 option when you call one of the pattern compiling
+functions.
.P
-If you set --enable-utf8 when compiling in an EBCDIC environment, PCRE expects
-its input to be either ASCII or UTF-8 (depending on the runtime option). It is
+If you set --enable-utf when compiling in an EBCDIC environment, PCRE expects
+its input to be either ASCII or UTF-8 (depending on the run-time option). It is
not possible to support both EBCDIC and UTF-8 codes in the same version of the
-library. Consequently, --enable-utf8 and --enable-ebcdic are mutually
+library. Consequently, --enable-utf and --enable-ebcdic are mutually
exclusive.
.
.
.SH "UNICODE CHARACTER PROPERTY SUPPORT"
.rs
.sp
-UTF-8 support allows PCRE to process character values greater than 255 in the
-strings that it handles. On its own, however, it does not provide any
+UTF support allows the libraries to process character codepoints up to 0x10ffff
+in the strings that they handle. On its own, however, it does not provide any
facilities for accessing the properties of such characters. If you want to be
able to use the pattern escapes \eP, \ep, and \eX, which refer to Unicode
character properties, you must add
.sp
--enable-unicode-properties
.sp
-to the \fBconfigure\fP command. This implies UTF-8 support, even if you have
+to the \fBconfigure\fP command. This implies UTF support, even if you have
not explicitly requested it.
.P
Including Unicode property support adds around 30K of tables to the PCRE
@@ -86,6 +129,27 @@
documentation.
.
.
+.SH "JUST-IN-TIME COMPILER SUPPORT"
+.rs
+.sp
+Just-in-time compiler support is included in the build by specifying
+.sp
+ --enable-jit
+.sp
+This support is available only for certain hardware architectures. If this
+option is set for an unsupported architecture, a compile time error occurs.
+See the
+.\" HREF
+\fBpcrejit\fP
+.\"
+documentation for a discussion of JIT usage. When JIT support is enabled,
+pcregrep automatically makes use of it, unless you add
+.sp
+ --disable-pcregrep-jit
+.sp
+to the "configure" command.
+.
+.
.SH "CODE VALUE OF NEWLINE"
.rs
.sp
@@ -132,22 +196,10 @@
called.
.
.
-.SH "BUILDING SHARED AND STATIC LIBRARIES"
-.rs
-.sp
-The PCRE building process uses \fBlibtool\fP to build both shared and static
-Unix libraries by default. You can suppress one of these by adding one of
-.sp
- --disable-shared
- --disable-static
-.sp
-to the \fBconfigure\fP command, as required.
-.
-.
.SH "POSIX MALLOC USAGE"
.rs
.sp
-When PCRE is called through the POSIX interface (see the
+When the 8-bit library is called through the POSIX interface (see the
.\" HREF
\fBpcreposix\fP
.\"
@@ -172,14 +224,15 @@
metacharacter). By default, two-byte values are used for these offsets, leading
to a maximum size for a compiled pattern of around 64K. This is sufficient to
handle all but the most gigantic patterns. Nevertheless, some people do want to
-process truyl enormous patterns, so it is possible to compile PCRE to use
+process truly enormous patterns, so it is possible to compile PCRE to use
three-byte or four-byte offsets by adding a setting such as
.sp
--with-link-size=3
.sp
-to the \fBconfigure\fP command. The value given must be 2, 3, or 4. Using
-longer offsets slows down the operation of PCRE because it has to load
-additional bytes when handling them.
+to the \fBconfigure\fP command. The value given must be 2, 3, or 4. For the
+16-bit library, a value of 3 is rounded up to 4. Using longer offsets slows
+down the operation of PCRE because it has to load additional data when handling
+them.
.
.
.SH "AVOIDING EXCESSIVE STACK USAGE"
@@ -260,7 +313,7 @@
.sp
to the \fBconfigure\fP command, the distributed tables are no longer used.
Instead, a program called \fBdftables\fP is compiled and run. This outputs the
-source for new set of tables, created in the default locale of your C runtime
+source for new set of tables, created in the default locale of your C run-time
system. (This method of replacing the tables does not work if you are cross
compiling, because \fBdftables\fP is run on the local host. If you need to
create alternative tables when cross compiling, you will have to do so "by
@@ -280,7 +333,7 @@
to the \fBconfigure\fP command. This setting implies
--enable-rebuild-chartables. You should only use it if you know that you are in
an EBCDIC environment (for example, an IBM mainframe operating system). The
---enable-ebcdic option is incompatible with --enable-utf8.
+--enable-ebcdic option is incompatible with --enable-utf.
.
.
.SH "PCREGREP OPTIONS FOR COMPRESSED FILE SUPPORT"
@@ -298,6 +351,23 @@
they are not.
.
.
+.SH "PCREGREP BUFFER SIZE"
+.rs
+.sp
+\fBpcregrep\fP uses an internal buffer to hold a "window" on the file it is
+scanning, in order to be able to output "before" and "after" lines when it
+finds a match. The size of the buffer is controlled by a parameter whose
+default value is 20K. The buffer itself is three times this size, but because
+of the way it is used for holding "before" lines, the longest line that is
+guaranteed to be processable is the parameter size. You can change the default
+parameter value by adding, for example,
+.sp
+ --with-pcregrep-bufsize=50K
+.sp
+to the \fBconfigure\fP command. The caller of \fPpcregrep\fP can, however,
+override this value by specifying a run-time option.
+.
+.
.SH "PCRETEST OPTION FOR LIBREADLINE SUPPORT"
.rs
.sp
@@ -333,7 +403,7 @@
.SH "SEE ALSO"
.rs
.sp
-\fBpcreapi\fP(3), \fBpcre_config\fP(3).
+\fBpcreapi\fP(3), \fBpcre16\fP, \fBpcre_config\fP(3).
.
.
.SH AUTHOR
@@ -350,6 +420,6 @@
.rs
.sp
.nf
-Last updated: 29 September 2009
-Copyright (c) 1997-2009 University of Cambridge.
+Last updated: 07 January 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcrecallout.3 pcre3-8.31/doc/pcrecallout.3
--- pcre3-8.12/doc/pcrecallout.3 2010-11-21 18:50:52.000000000 +0000
+++ pcre3-8.31/doc/pcrecallout.3 2012-03-31 18:00:11.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRECALLOUT 3
+.TH PCRECALLOUT 3 "08 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PCRE CALLOUTS"
@@ -6,11 +6,14 @@
.sp
.B int (*pcre_callout)(pcre_callout_block *);
.PP
+.B int (*pcre16_callout)(pcre16_callout_block *);
+.PP
PCRE provides a feature called "callout", which is a means of temporarily
passing control to the caller of PCRE in the middle of pattern matching. The
caller of PCRE provides an external function by putting its entry point in the
-global variable \fIpcre_callout\fP. By default, this variable contains NULL,
-which disables all calling out.
+global variable \fIpcre_callout\fP (\fIpcre16_callout\fP for the 16-bit
+library). By default, this variable contains NULL, which disables all calling
+out.
.P
Within a regular expression, (?C) indicates the points at which the external
function is to be called. Different callout points can be identified by putting
@@ -19,10 +22,9 @@
.sp
(?C1)abc(?C2)def
.sp
-If the PCRE_AUTO_CALLOUT option bit is set when \fBpcre_compile()\fP or
-\fBpcre_compile2()\fP is called, PCRE automatically inserts callouts, all with
-number 255, before each item in the pattern. For example, if PCRE_AUTO_CALLOUT
-is used with the pattern
+If the PCRE_AUTO_CALLOUT option bit is set when a pattern is compiled, PCRE
+automatically inserts callouts, all with number 255, before each item in the
+pattern. For example, if PCRE_AUTO_CALLOUT is used with the pattern
.sp
A(\ed{2}|--)
.sp
@@ -39,6 +41,10 @@
command has an option that sets automatic callouts; when it is used, the output
indicates how the pattern is matched. This is useful information when you are
trying to optimize the performance of a particular pattern.
+.P
+The use of callouts in a pattern makes it ineligible for optimization by the
+just-in-time compiler. Studying such a pattern with the PCRE_STUDY_JIT_COMPILE
+option always fails.
.
.
.SH "MISSING CALLOUTS"
@@ -61,35 +67,38 @@
been scanned far enough.
.P
You can disable these optimizations by passing the PCRE_NO_START_OPTIMIZE
-option to \fBpcre_compile()\fP, \fBpcre_exec()\fP, or \fBpcre_dfa_exec()\fP,
-or by starting the pattern with (*NO_START_OPT). This slows down the matching
-process, but does ensure that callouts such as the example above are obeyed.
+option to the matching function, or by starting the pattern with
+(*NO_START_OPT). This slows down the matching process, but does ensure that
+callouts such as the example above are obeyed.
.
.
.SH "THE CALLOUT INTERFACE"
.rs
.sp
During matching, when PCRE reaches a callout point, the external function
-defined by \fIpcre_callout\fP is called (if it is set). This applies to both
-the \fBpcre_exec()\fP and the \fBpcre_dfa_exec()\fP matching functions. The
-only argument to the callout function is a pointer to a \fBpcre_callout\fP
-block. This structure contains the following fields:
-.sp
- int \fIversion\fP;
- int \fIcallout_number\fP;
- int *\fIoffset_vector\fP;
- const char *\fIsubject\fP;
- int \fIsubject_length\fP;
- int \fIstart_match\fP;
- int \fIcurrent_position\fP;
- int \fIcapture_top\fP;
- int \fIcapture_last\fP;
- void *\fIcallout_data\fP;
- int \fIpattern_position\fP;
- int \fInext_item_length\fP;
+defined by \fIpcre_callout\fP or \fIpcre16_callout\fP is called (if it is set).
+This applies to both normal and DFA matching. The only argument to the callout
+function is a pointer to a \fBpcre_callout\fP or \fBpcre16_callout\fP block.
+These structures contains the following fields:
+.sp
+ int \fIversion\fP;
+ int \fIcallout_number\fP;
+ int *\fIoffset_vector\fP;
+ const char *\fIsubject\fP; (8-bit version)
+ PCRE_SPTR16 \fIsubject\fP; (16-bit version)
+ int \fIsubject_length\fP;
+ int \fIstart_match\fP;
+ int \fIcurrent_position\fP;
+ int \fIcapture_top\fP;
+ int \fIcapture_last\fP;
+ void *\fIcallout_data\fP;
+ int \fIpattern_position\fP;
+ int \fInext_item_length\fP;
+ const unsigned char *\fImark\fP; (8-bit version)
+ const PCRE_UCHAR16 *\fImark\fP; (16-bit version)
.sp
The \fIversion\fP field is an integer containing the version number of the
-block format. The initial version was 0; the current version is 1. The version
+block format. The initial version was 0; the current version is 2. The version
number will change again in future if additional fields are added, but the
intention is never to remove any of the existing fields.
.P
@@ -98,14 +107,14 @@
automatically generated callouts).
.P
The \fIoffset_vector\fP field is a pointer to the vector of offsets that was
-passed by the caller to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP. When
-\fBpcre_exec()\fP is used, the contents can be inspected in order to extract
+passed by the caller to the matching function. When \fBpcre_exec()\fP or
+\fBpcre16_exec()\fP is used, the contents can be inspected, in order to extract
substrings that have been matched so far, in the same way as for extracting
-substrings after a match has completed. For \fBpcre_dfa_exec()\fP this field is
-not useful.
+substrings after a match has completed. For the DFA matching functions, this
+field is not useful.
.P
The \fIsubject\fP and \fIsubject_length\fP fields contain copies of the values
-that were passed to \fBpcre_exec()\fP.
+that were passed to the matching function.
.P
The \fIstart_match\fP field normally contains the offset within the subject at
which the current match attempt started. However, if the escape sequence \eK
@@ -117,41 +126,47 @@
The \fIcurrent_position\fP field contains the offset within the subject of the
current match pointer.
.P
-When the \fBpcre_exec()\fP function is used, the \fIcapture_top\fP field
-contains one more than the number of the highest numbered captured substring so
-far. If no substrings have been captured, the value of \fIcapture_top\fP is
-one. This is always the case when \fBpcre_dfa_exec()\fP is used, because it
-does not support captured substrings.
+When the \fBpcre_exec()\fP or \fBpcre16_exec()\fP is used, the
+\fIcapture_top\fP field contains one more than the number of the highest
+numbered captured substring so far. If no substrings have been captured, the
+value of \fIcapture_top\fP is one. This is always the case when the DFA
+functions are used, because they do not support captured substrings.
.P
The \fIcapture_last\fP field contains the number of the most recently captured
substring. If no substrings have been captured, its value is -1. This is always
-the case when \fBpcre_dfa_exec()\fP is used.
+the case for the DFA matching functions.
.P
-The \fIcallout_data\fP field contains a value that is passed to
-\fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP specifically so that it can be
-passed back in callouts. It is passed in the \fIpcre_callout\fP field of the
-\fBpcre_extra\fP data structure. If no such data was passed, the value of
-\fIcallout_data\fP in a \fBpcre_callout\fP block is NULL. There is a
-description of the \fBpcre_extra\fP structure in the
+The \fIcallout_data\fP field contains a value that is passed to a matching
+function specifically so that it can be passed back in callouts. It is passed
+in the \fIcallout_data\fP field of a \fBpcre_extra\fP or \fBpcre16_extra\fP
+data structure. If no such data was passed, the value of \fIcallout_data\fP in
+a callout block is NULL. There is a description of the \fBpcre_extra\fP
+structure in the
.\" HREF
\fBpcreapi\fP
.\"
documentation.
.P
-The \fIpattern_position\fP field is present from version 1 of the
-\fIpcre_callout\fP structure. It contains the offset to the next item to be
-matched in the pattern string.
-.P
-The \fInext_item_length\fP field is present from version 1 of the
-\fIpcre_callout\fP structure. It contains the length of the next item to be
-matched in the pattern string. When the callout immediately precedes an
-alternation bar, a closing parenthesis, or the end of the pattern, the length
-is zero. When the callout precedes an opening parenthesis, the length is that
-of the entire subpattern.
+The \fIpattern_position\fP field is present from version 1 of the callout
+structure. It contains the offset to the next item to be matched in the pattern
+string.
+.P
+The \fInext_item_length\fP field is present from version 1 of the callout
+structure. It contains the length of the next item to be matched in the pattern
+string. When the callout immediately precedes an alternation bar, a closing
+parenthesis, or the end of the pattern, the length is zero. When the callout
+precedes an opening parenthesis, the length is that of the entire subpattern.
.P
The \fIpattern_position\fP and \fInext_item_length\fP fields are intended to
help in distinguishing between different automatic callouts, which all have the
same callout number. However, they are set for all callouts.
+.P
+The \fImark\fP field is present from version 2 of the callout structure. In
+callouts from \fBpcre_exec()\fP or \fBpcre16_exec()\fP it contains a pointer to
+the zero-terminated name of the most recently passed (*MARK), (*PRUNE), or
+(*THEN) item in the match, or NULL if no such items have been passed. Instances
+of (*PRUNE) or (*THEN) without a name do not obliterate a previous (*MARK). In
+callouts from the DFA matching functions this field always contains NULL.
.
.
.SH "RETURN VALUES"
@@ -161,8 +176,7 @@
matching proceeds as normal. If the value is greater than zero, matching fails
at the current point, but the testing of other matching possibilities goes
ahead, just as if a lookahead assertion had failed. If the value is less than
-zero, the match is abandoned, and \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP
-returns the negative value.
+zero, the match is abandoned, the matching function returns the negative value.
.P
Negative values should normally be chosen from the set of PCRE_ERROR_xxx
values. In particular, PCRE_ERROR_NOMATCH forces a standard "no match" failure.
@@ -184,6 +198,6 @@
.rs
.sp
.nf
-Last updated: 21 November 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 08 Janurary 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcrecompat.3 pcre3-8.31/doc/pcrecompat.3
--- pcre3-8.12/doc/pcrecompat.3 2010-11-24 17:38:33.000000000 +0000
+++ pcre3-8.31/doc/pcrecompat.3 2012-06-01 17:50:56.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRECOMPAT 3
+.TH PCRECOMPAT 3 "08 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "DIFFERENCES BETWEEN PCRE AND PERL"
@@ -8,22 +8,19 @@
regular expressions. The differences described here are with respect to Perl
versions 5.10 and above.
.P
-1. PCRE has only a subset of Perl's UTF-8 and Unicode support. Details of what
-it does have are given in the
-.\" HTML
-.\"
-section on UTF-8 support
-.\"
-in the main
+1. PCRE has only a subset of Perl's Unicode support. Details of what it does
+have are given in the
.\" HREF
-\fBpcre\fP
+\fBpcreunicode\fP
.\"
page.
.P
-2. PCRE does not allow repeat quantifiers on lookahead assertions. Perl permits
-them, but they do not mean what you might think. For example, (?!a){3} does
-not assert that the next three characters are not "a". It just asserts that the
-next character is not "a" three times.
+2. PCRE allows repeat quantifiers only on parenthesized assertions, but they do
+not mean what you might think. For example, (?!a){3} does not assert that the
+next three characters are not "a". It just asserts that the next character is
+not "a" three times (in principle: PCRE optimizes this to run the assertion
+just once). Perl allows repeat quantifiers on other assertions such as \eb, but
+these do not seem to have any use.
.P
3. Capturing subpatterns that occur inside negative lookahead assertions are
counted, but their entries in the offsets vector are never set. Perl sets its
@@ -37,9 +34,12 @@
represent a binary zero.
.P
5. The following Perl escape sequences are not supported: \el, \eu, \eL,
-\eU, and \eN. In fact these are implemented by Perl's general string-handling
-and are not part of its pattern matching engine. If any of these are
-encountered by PCRE, an error is generated.
+\eU, and \eN when followed by a character name or Unicode value. (\eN on its
+own, matching a non-newline character, is supported.) In fact these are
+implemented by Perl's general string-handling and are not part of its pattern
+matching engine. If any of these are encountered by PCRE, an error is
+generated by default. However, if the PCRE_JAVASCRIPT_COMPAT option is set,
+\eU and \eu are interpreted as JavaScript interprets them.
.P
6. The Perl escape sequences \ep, \eP, and \eX are supported only if PCRE is
built with Unicode character property support. The properties that can be
@@ -50,7 +50,11 @@
the internal representation of Unicode characters, there is no need to
implement the somewhat messy concept of surrogates."
.P
-7. PCRE does support the \eQ...\eE escape for quoting substrings. Characters in
+7. PCRE implements a simpler version of \eX than Perl, which changed to make
+\eX match what Unicode calls an "extended grapheme cluster". This is more
+complicated than an extended Unicode sequence, which is what PCRE matches.
+.P
+8. PCRE does support the \eQ...\eE escape for quoting substrings. Characters in
between are treated as literals. This is slightly different from Perl in that $
and @ are also handled as literals inside the quotes. In Perl, they cause
variable interpolation (but of course PCRE does not have variables). Note the
@@ -66,7 +70,7 @@
.sp
The \eQ...\eE sequence is recognized both inside and outside character classes.
.P
-8. Fairly obviously, PCRE does not support the (?{code}) and (??{code})
+9. Fairly obviously, PCRE does not support the (?{code}) and (??{code})
constructions. However, there is support for recursive patterns. This is not
available in Perl 5.8, but it is in Perl 5.10. Also, the PCRE "callout"
feature allows an external function to be called during pattern matching. See
@@ -76,9 +80,11 @@
.\"
documentation for details.
.P
-9. Subpatterns that are called recursively or as "subroutines" are always
-treated as atomic groups in PCRE. This is like Python, but unlike Perl. There
-is a discussion of an example that explains this in more detail in the
+10. Subpatterns that are called as subroutines (whether or not recursively) are
+always treated as atomic groups in PCRE. This is like Python, but unlike Perl.
+Captured values that are set outside a subroutine call can be reference from
+inside in PCRE, but not in Perl. There is a discussion that explains these
+differences in more detail in the
.\" HTML
.\"
section on recursion differences from Perl
@@ -89,11 +95,22 @@
.\"
page.
.P
-10. There are some differences that are concerned with the settings of captured
+11. If any of the backtracking control verbs are used in an assertion or in a
+subpattern that is called as a subroutine (whether or not recursively), their
+effect is confined to that subpattern; it does not extend to the surrounding
+pattern. This is not always the case in Perl. In particular, if (*THEN) is
+present in a group that is called as a subroutine, its action is limited to
+that group, even if the group does not contain any | characters. There is one
+exception to this: the name from a *(MARK), (*PRUNE), or (*THEN) that is
+encountered in a successful positive assertion \fIis\fP passed back when a
+match succeeds (compare capturing parentheses in assertions). Note that such
+subpatterns are processed as anchored at the point where they are tested.
+.P
+12. There are some differences that are concerned with the settings of captured
strings when part of a pattern is repeated. For example, matching "aba" against
the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE it is set to "b".
.P
-11. PCRE's handling of duplicate subpattern numbers and duplicate subpattern
+13. PCRE's handling of duplicate subpattern numbers and duplicate subpattern
names is not as general as Perl's. This is a consequence of the fact the PCRE
works internally just with numbers, using an external table to translate
between numbers and names. In particular, a pattern such as (?|(?A)|(?\fP. When there is more than one pattern
-(specified by the use of \fB-e\fP and/or \fB-f\fP), each pattern is applied to
-each line in the order in which they are defined, except that all the \fB-e\fP
-patterns are tried before the \fB-f\fP patterns.
+The amount of memory used for buffering files that are being scanned is
+controlled by a parameter that can be set by the \fB--buffer-size\fP option.
+The default value for this parameter is specified when \fBpcregrep\fP is built,
+with the default default being 20K. A block of memory three times this size is
+used (to allow for buffering "before" and "after" lines). An error occurs if a
+line overflows the buffer.
+.P
+Patterns are limited to 8K or BUFSIZ bytes, whichever is the greater. BUFSIZ is
+defined in \fB\fP. When there is more than one pattern (specified by
+the use of \fB-e\fP and/or \fB-f\fP), each pattern is applied to each line in
+the order in which they are defined, except that all the \fB-e\fP patterns are
+tried before the \fB-f\fP patterns.
.P
By default, as soon as one pattern matches (or fails to match when \fB-v\fP is
used), no further patterns are considered. However, if \fB--colour\fP (or
@@ -76,9 +82,7 @@
If the \fBLC_ALL\fP or \fBLC_CTYPE\fP environment variable is set,
\fBpcregrep\fP uses the value to set a locale when calling the PCRE library.
The \fB--locale\fP option can be used to override this.
-.P
-\fBzpcregrep\fR is a wrapper script that allows pcregrep to work on
-gzip compressed files.
+.
.
.SH "SUPPORT FOR COMPRESSED FILES"
.rs
@@ -90,16 +94,27 @@
appropriate support is not present, files are treated as plain text. The
standard input is always so treated.
.
+.
+.SH "BINARY FILES"
+.rs
+.sp
+By default, a file that contains a binary zero byte within the first 1024 bytes
+is identified as a binary file, and is processed specially. (GNU grep also
+identifies binary files in this manner.) See the \fB--binary-files\fP option
+for a means of changing the way binary files are handled.
+.
+.
.SH OPTIONS
.rs
.sp
The order in which some of the options appear can affect the output. For
example, both the \fB-h\fP and \fB-l\fP options affect the printing of file
names. Whichever comes later in the command line will be the one that takes
-effect.
+effect. Numerical values for options may be followed by K or M, to signify
+multiplication by 1024 or 1024*1024 respectively.
.TP 10
\fB--\fP
-This terminate the list of options. It is useful if the next item on the
+This terminates the list of options. It is useful if the next item on the
command line starts with a hyphen but is not an option. This allows for the
processing of patterns and filenames that start with hyphens.
.TP
@@ -111,6 +126,10 @@
of \fInumber\fP is expected to be relatively small. However, \fBpcregrep\fP
guarantees to have up to 8K of following text available for context output.
.TP
+\fB-a\fP, \fB--text\fP
+Treat binary files as text. This is equivalent to
+\fB--binary-files\fP=\fItext\fP.
+.TP
\fB-B\fP \fInumber\fP, \fB--before-context=\fP\fInumber\fP
Output \fInumber\fP lines of context before each matching line. If filenames
and/or line numbers are being output, a hyphen separator is used instead of a
@@ -119,6 +138,21 @@
of \fInumber\fP is expected to be relatively small. However, \fBpcregrep\fP
guarantees to have up to 8K of preceding text available for context output.
.TP
+\fB--binary-files=\fP\fIword\fP
+Specify how binary files are to be processed. If the word is "binary" (the
+default), pattern matching is performed on binary files, but the only output is
+"Binary file matches" when a match succeeds. If the word is "text",
+which is equivalent to the \fB-a\fP or \fB--text\fP option, binary files are
+processed in the same way as any other file. In this case, when a match
+succeeds, the output may be binary garbage, which can have nasty effects if
+sent to a terminal. If the word is "without-match", which is equivalent to the
+\fB-I\fP option, binary files are not processed at all; they are assumed not to
+be of interest.
+.TP
+\fB--buffer-size=\fP\fInumber\fP
+Set the parameter that controls how much memory is used for buffering files
+that are being scanned.
+.TP
\fB-C\fP \fInumber\fP, \fB--context=\fP\fInumber\fP
Output \fInumber\fP lines of context both before and after each matching line.
This is equivalent to setting both \fB-A\fP and \fB-B\fP to the same value.
@@ -214,11 +248,21 @@
filename can be given as "-" to refer to the standard input. When \fB-f\fP is
used, patterns specified on the command line using \fB-e\fP may also be
present; they are tested before the file's patterns. However, no other pattern
-is taken from the command line; all arguments are treated as file names. There
-is an overall maximum of 100 patterns. Trailing white space is removed from
-each line, and blank lines are ignored. An empty file contains no patterns and
-therefore matches nothing. See also the comments about multiple patterns versus
-a single pattern with alternatives in the description of \fB-e\fP above.
+is taken from the command line; all arguments are treated as the names of paths
+to be searched. There is an overall maximum of 100 patterns. Trailing white
+space is removed from each line, and blank lines are ignored. An empty file
+contains no patterns and therefore matches nothing. See also the comments about
+multiple patterns versus a single pattern with alternatives in the description
+of \fB-e\fP above.
+.TP
+\fB--file-list\fP=\fIfilename\fP
+Read a list of files to be searched from the given file, one per line. Trailing
+white space is removed from each line, and blank lines are ignored. These files
+are searched before any others that may be listed on the command line. The
+filename can be given as "-" to refer to the standard input. If \fB--file\fP
+and \fB--file-list\fP are both specified as "-", patterns are read first. This
+is useful only when the standard input is a terminal, from which further lines
+(the list of files) can be read after an end-of-file indication.
.TP
\fB--file-offsets\fP
Instead of showing lines or parts of lines that match, show each match as an
@@ -245,6 +289,10 @@
Output a help message, giving brief details of the command options and file
type support, and then exit.
.TP
+\fB-I\fP
+Treat binary files as never matching. This is equivalent to
+\fB--binary-files\fP=\fIwithout-match\fP.
+.TP
\fB-i\fP, \fB--ignore-case\fP
Ignore upper/lower case distinctions during comparisons.
.TP
@@ -360,7 +408,7 @@
which recognizes any of the preceding three types, and an "any" convention, in
which any Unicode line ending sequence is assumed to end a line. The Unicode
sequences are the three just mentioned, plus VT (vertical tab, U+000B), FF
-(formfeed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and
+(form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and
PS (paragraph separator, U+2029).
.sp
When the PCRE library is built, a default line-ending sequence is specified.
@@ -378,6 +426,13 @@
output, it precedes the line number. This option is forced if
\fB--line-offsets\fP is used.
.TP
+\fB--no-jit\fP
+If the PCRE library is built with support for just-in-time compiling (which
+speeds up matching), \fBpcregrep\fP automatically makes use of this, unless it
+was explicitly disabled at build time. This option can be used to disable the
+use of JIT at run time. It is provided for testing and working round problems.
+It should never be needed in normal use.
+.TP
\fB-o\fP, \fB--only-matching\fP
Show only the part of the line that matched a pattern instead of the whole
line. In this mode, no context is shown. That is, the \fB-A\fP, \fB-B\fP, and
@@ -466,13 +521,14 @@
.rs
.sp
Many of the short and long forms of \fBpcregrep\fP's options are the same
-as in the GNU \fBgrep\fP program (version 2.5.4). Any long option of the form
+as in the GNU \fBgrep\fP program. Any long option of the form
\fB--xxx-regexp\fP (GNU terminology) is also available as \fB--xxx-regex\fP
-(PCRE terminology). However, the \fB--file-offsets\fP, \fB--include-dir\fP,
-\fB--line-offsets\fP, \fB--locale\fP, \fB--match-limit\fP, \fB-M\fP,
-\fB--multiline\fP, \fB-N\fP, \fB--newline\fP, \fB--recursion-limit\fP,
-\fB-u\fP, and \fB--utf-8\fP options are specific to \fBpcregrep\fP, as is the
-use of the \fB--only-matching\fP option with a capturing parentheses number.
+(PCRE terminology). However, the \fB--file-list\fP, \fB--file-offsets\fP,
+\fB--include-dir\fP, \fB--line-offsets\fP, \fB--locale\fP, \fB--match-limit\fP,
+\fB-M\fP, \fB--multiline\fP, \fB-N\fP, \fB--newline\fP,
+\fB--recursion-limit\fP, \fB-u\fP, and \fB--utf-8\fP options are specific to
+\fBpcregrep\fP, as is the use of the \fB--only-matching\fP option with a
+capturing parentheses number.
.P
Although most of the common options work the same way, a few are different in
\fBpcregrep\fP. For example, the \fB--include\fP option's argument is a glob
@@ -534,10 +590,10 @@
.rs
.sp
Exit status is 0 if any matches were found, 1 if no matches were found, and 2
-for syntax errors and non-existent or inaccessible files (even if matches were
-found in other files) or too many matching errors. Using the \fB-s\fP option to
-suppress error messages about inaccessble files does not affect the return
-code.
+for syntax errors, overlong lines, non-existent or inaccessible files (even if
+matches were found in other files) or too many matching errors. Using the
+\fB-s\fP option to suppress error messages about inaccessible files does not
+affect the return code.
.
.
.SH "SEE ALSO"
@@ -560,6 +616,6 @@
.rs
.sp
.nf
-Last updated: 14 January 2011
-Copyright (c) 1997-2011 University of Cambridge.
+Last updated: 04 March 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcregrep.txt pcre3-8.31/doc/pcregrep.txt
--- pcre3-8.12/doc/pcregrep.txt 2011-01-15 17:27:45.000000000 +0000
+++ pcre3-8.31/doc/pcregrep.txt 2012-07-06 09:55:27.000000000 +0000
@@ -49,19 +49,26 @@
What defines a line boundary is controlled by the -N (--newline)
option.
- Patterns are limited to 8K or BUFSIZ characters, whichever is the
- greater. BUFSIZ is defined in . When there is more than one
- pattern (specified by the use of -e and/or -f), each pattern is applied
- to each line in the order in which they are defined, except that all
- the -e patterns are tried before the -f patterns.
+ The amount of memory used for buffering files that are being scanned is
+ controlled by a parameter that can be set by the --buffer-size option.
+ The default value for this parameter is specified when pcregrep is
+ built, with the default default being 20K. A block of memory three
+ times this size is used (to allow for buffering "before" and "after"
+ lines). An error occurs if a line overflows the buffer.
+
+ Patterns are limited to 8K or BUFSIZ bytes, whichever is the greater.
+ BUFSIZ is defined in . When there is more than one pattern
+ (specified by the use of -e and/or -f), each pattern is applied to each
+ line in the order in which they are defined, except that all the -e
+ patterns are tried before the -f patterns.
- By default, as soon as one pattern matches (or fails to match when -v
- is used), no further patterns are considered. However, if --colour (or
+ By default, as soon as one pattern matches (or fails to match when -v
+ is used), no further patterns are considered. However, if --colour (or
--color) is used to colour the matching substrings, or if --only-match-
- ing, --file-offsets, or --line-offsets is used to output only the part
- of the line that matched (either shown literally, or as an offset),
- scanning resumes immediately following the match, so that further
- matches on the same line can be found. If there are multiple patterns,
+ ing, --file-offsets, or --line-offsets is used to output only the part
+ of the line that matched (either shown literally, or as an offset),
+ scanning resumes immediately following the match, so that further
+ matches on the same line can be found. If there are multiple patterns,
they are all tried on the remainder of the line, but patterns that fol-
low the one that matched are not tried on the earlier part of the line.
@@ -69,36 +76,46 @@
in which multiple patterns are specified can affect the output when one
of the above options is used.
- Patterns that can match an empty string are accepted, but empty string
+ Patterns that can match an empty string are accepted, but empty string
matches are never recognized. An example is the pattern
- "(super)?(man)?", in which all components are optional. This pattern
- finds all occurrences of both "super" and "man"; the output differs
- from matching with "super|man" when only the matching substrings are
+ "(super)?(man)?", in which all components are optional. This pattern
+ finds all occurrences of both "super" and "man"; the output differs
+ from matching with "super|man" when only the matching substrings are
being shown.
- If the LC_ALL or LC_CTYPE environment variable is set, pcregrep uses
- the value to set a locale when calling the PCRE library. The --locale
+ If the LC_ALL or LC_CTYPE environment variable is set, pcregrep uses
+ the value to set a locale when calling the PCRE library. The --locale
option can be used to override this.
SUPPORT FOR COMPRESSED FILES
- It is possible to compile pcregrep so that it uses libz or libbz2 to
- read files whose names end in .gz or .bz2, respectively. You can find
+ It is possible to compile pcregrep so that it uses libz or libbz2 to
+ read files whose names end in .gz or .bz2, respectively. You can find
out whether your binary has support for one or both of these file types
by running it with the --help option. If the appropriate support is not
- present, files are treated as plain text. The standard input is always
+ present, files are treated as plain text. The standard input is always
so treated.
+BINARY FILES
+
+ By default, a file that contains a binary zero byte within the first
+ 1024 bytes is identified as a binary file, and is processed specially.
+ (GNU grep also identifies binary files in this manner.) See the
+ --binary-files option for a means of changing the way binary files are
+ handled.
+
+
OPTIONS
- The order in which some of the options appear can affect the output.
- For example, both the -h and -l options affect the printing of file
- names. Whichever comes later in the command line will be the one that
- takes effect.
+ The order in which some of the options appear can affect the output.
+ For example, both the -h and -l options affect the printing of file
+ names. Whichever comes later in the command line will be the one that
+ takes effect. Numerical values for options may be followed by K or M,
+ to signify multiplication by 1024 or 1024*1024 respectively.
- -- This terminate the list of options. It is useful if the next
+ -- This terminates the list of options. It is useful if the next
item on the command line starts with a hyphen but is not an
option. This allows for the processing of patterns and file-
names that start with hyphens.
@@ -113,16 +130,37 @@
pcregrep guarantees to have up to 8K of following text avail-
able for context output.
+ -a, --text
+ Treat binary files as text. This is equivalent to --binary-
+ files=text.
+
-B number, --before-context=number
- Output number lines of context before each matching line. If
+ Output number lines of context before each matching line. If
filenames and/or line numbers are being output, a hyphen sep-
- arator is used instead of a colon for the context lines. A
- line containing "--" is output between each group of lines,
- unless they are in fact contiguous in the input file. The
- value of number is expected to be relatively small. However,
+ arator is used instead of a colon for the context lines. A
+ line containing "--" is output between each group of lines,
+ unless they are in fact contiguous in the input file. The
+ value of number is expected to be relatively small. However,
pcregrep guarantees to have up to 8K of preceding text avail-
able for context output.
+ --binary-files=word
+ Specify how binary files are to be processed. If the word is
+ "binary" (the default), pattern matching is performed on
+ binary files, but the only output is "Binary file
+ matches" when a match succeeds. If the word is "text", which
+ is equivalent to the -a or --text option, binary files are
+ processed in the same way as any other file. In this case,
+ when a match succeeds, the output may be binary garbage,
+ which can have nasty effects if sent to a terminal. If the
+ word is "without-match", which is equivalent to the -I
+ option, binary files are not processed at all; they are
+ assumed not to be of interest.
+
+ --buffer-size=number
+ Set the parameter that controls how much memory is used for
+ buffering files that are being scanned.
+
-C number, --context=number
Output number lines of context both before and after each
matching line. This is equivalent to setting both -A and -B
@@ -236,12 +274,23 @@
specified on the command line using -e may also be present;
they are tested before the file's patterns. However, no other
pattern is taken from the command line; all arguments are
- treated as file names. There is an overall maximum of 100
- patterns. Trailing white space is removed from each line, and
- blank lines are ignored. An empty file contains no patterns
- and therefore matches nothing. See also the comments about
- multiple patterns versus a single pattern with alternatives
- in the description of -e above.
+ treated as the names of paths to be searched. There is an
+ overall maximum of 100 patterns. Trailing white space is
+ removed from each line, and blank lines are ignored. An empty
+ file contains no patterns and therefore matches nothing. See
+ also the comments about multiple patterns versus a single
+ pattern with alternatives in the description of -e above.
+
+ --file-list=filename
+ Read a list of files to be searched from the given file, one
+ per line. Trailing white space is removed from each line, and
+ blank lines are ignored. These files are searched before any
+ others that may be listed on the command line. The filename
+ can be given as "-" to refer to the standard input. If --file
+ and --file-list are both specified as "-", patterns are read
+ first. This is useful only when the standard input is a ter-
+ minal, from which further lines (the list of files) can be
+ read after an end-of-file indication.
--file-offsets
Instead of showing lines or parts of lines that match, show
@@ -270,6 +319,9 @@
--help Output a help message, giving brief details of the command
options and file type support, and then exit.
+ -I Treat binary files as never matching. This is equivalent to
+ --binary-files=without-match.
+
-i, --ignore-case
Ignore upper/lower case distinctions during comparisons.
@@ -277,38 +329,38 @@
When pcregrep is searching the files in a directory as a con-
sequence of the -r (recursive search) option, only those reg-
ular files whose names match the pattern are included. Subdi-
- rectories are always included and searched recursively, sub-
+ rectories are always included and searched recursively, sub-
ject to the --include-dir and --exclude-dir options. The pat-
tern is a PCRE regular expression, and is matched against the
- final component of the file name (not the entire path). If a
+ final component of the file name (not the entire path). If a
file name matches both --include and --exclude, it is
excluded. There is no short form for this option.
--include-dir=pattern
- When pcregrep is searching the contents of a directory as a
- consequence of the -r (recursive search) option, only those
- subdirectories whose names match the pattern are included.
- (Note that the --include option does not affect subdirecto-
- ries.) The pattern is a PCRE regular expression, and is
- matched against the final component of the name (not the
- entire path). If a subdirectory name matches both --include-
+ When pcregrep is searching the contents of a directory as a
+ consequence of the -r (recursive search) option, only those
+ subdirectories whose names match the pattern are included.
+ (Note that the --include option does not affect subdirecto-
+ ries.) The pattern is a PCRE regular expression, and is
+ matched against the final component of the name (not the
+ entire path). If a subdirectory name matches both --include-
dir and --exclude-dir, it is excluded. There is no short form
for this option.
-L, --files-without-match
- Instead of outputting lines from the files, just output the
- names of the files that do not contain any lines that would
- have been output. Each file name is output once, on a sepa-
+ Instead of outputting lines from the files, just output the
+ names of the files that do not contain any lines that would
+ have been output. Each file name is output once, on a sepa-
rate line.
-l, --files-with-matches
- Instead of outputting lines from the files, just output the
+ Instead of outputting lines from the files, just output the
names of the files containing lines that would have been out-
- put. Each file name is output once, on a separate line.
- Searching normally stops as soon as a matching line is found
- in a file. However, if the -c (count) option is also used,
- matching continues in order to obtain the correct count, and
- those files that have at least one match are listed along
+ put. Each file name is output once, on a separate line.
+ Searching normally stops as soon as a matching line is found
+ in a file. However, if the -c (count) option is also used,
+ matching continues in order to obtain the correct count, and
+ those files that have at least one match are listed along
with their counts. Using this option with -c is a way of sup-
pressing the listing of files with no matches.
@@ -318,116 +370,123 @@
input)" is used. There is no short form for this option.
--line-buffered
- When this option is given, input is read and processed line
- by line, and the output is flushed after each write. By
- default, input is read in large chunks, unless pcregrep can
- determine that it is reading from a terminal (which is cur-
- rently possible only in Unix environments). Output to termi-
- nal is normally automatically flushed by the operating sys-
- tem. This option can be useful when the input or output is
- attached to a pipe and you do not want pcregrep to buffer up
- large amounts of data. However, its use will affect perfor-
+ When this option is given, input is read and processed line
+ by line, and the output is flushed after each write. By
+ default, input is read in large chunks, unless pcregrep can
+ determine that it is reading from a terminal (which is cur-
+ rently possible only in Unix environments). Output to termi-
+ nal is normally automatically flushed by the operating sys-
+ tem. This option can be useful when the input or output is
+ attached to a pipe and you do not want pcregrep to buffer up
+ large amounts of data. However, its use will affect perfor-
mance, and the -M (multiline) option ceases to work.
--line-offsets
- Instead of showing lines or parts of lines that match, show
+ Instead of showing lines or parts of lines that match, show
each match as a line number, the offset from the start of the
- line, and a length. The line number is terminated by a colon
- (as usual; see the -n option), and the offset and length are
- separated by a comma. In this mode, no context is shown.
- That is, the -A, -B, and -C options are ignored. If there is
- more than one match in a line, each of them is shown sepa-
+ line, and a length. The line number is terminated by a colon
+ (as usual; see the -n option), and the offset and length are
+ separated by a comma. In this mode, no context is shown.
+ That is, the -A, -B, and -C options are ignored. If there is
+ more than one match in a line, each of them is shown sepa-
rately. This option is mutually exclusive with --file-offsets
and --only-matching.
--locale=locale-name
- This option specifies a locale to be used for pattern match-
- ing. It overrides the value in the LC_ALL or LC_CTYPE envi-
- ronment variables. If no locale is specified, the PCRE
- library's default (usually the "C" locale) is used. There is
+ This option specifies a locale to be used for pattern match-
+ ing. It overrides the value in the LC_ALL or LC_CTYPE envi-
+ ronment variables. If no locale is specified, the PCRE
+ library's default (usually the "C" locale) is used. There is
no short form for this option.
--match-limit=number
- Processing some regular expression patterns can require a
- very large amount of memory, leading in some cases to a pro-
- gram crash if not enough is available. Other patterns may
- take a very long time to search for all possible matching
- strings. The pcre_exec() function that is called by pcregrep
- to do the matching has two parameters that can limit the
+ Processing some regular expression patterns can require a
+ very large amount of memory, leading in some cases to a pro-
+ gram crash if not enough is available. Other patterns may
+ take a very long time to search for all possible matching
+ strings. The pcre_exec() function that is called by pcregrep
+ to do the matching has two parameters that can limit the
resources that it uses.
- The --match-limit option provides a means of limiting
+ The --match-limit option provides a means of limiting
resource usage when processing patterns that are not going to
match, but which have a very large number of possibilities in
- their search trees. The classic example is a pattern that
- uses nested unlimited repeats. Internally, PCRE uses a func-
- tion called match() which it calls repeatedly (sometimes
- recursively). The limit set by --match-limit is imposed on
- the number of times this function is called during a match,
- which has the effect of limiting the amount of backtracking
+ their search trees. The classic example is a pattern that
+ uses nested unlimited repeats. Internally, PCRE uses a func-
+ tion called match() which it calls repeatedly (sometimes
+ recursively). The limit set by --match-limit is imposed on
+ the number of times this function is called during a match,
+ which has the effect of limiting the amount of backtracking
that can take place.
The --recursion-limit option is similar to --match-limit, but
instead of limiting the total number of times that match() is
called, it limits the depth of recursive calls, which in turn
- limits the amount of memory that can be used. The recursion
- depth is a smaller number than the total number of calls,
+ limits the amount of memory that can be used. The recursion
+ depth is a smaller number than the total number of calls,
because not all calls to match() are recursive. This limit is
of use only if it is set smaller than --match-limit.
- There are no short forms for these options. The default set-
- tings are specified when the PCRE library is compiled, with
+ There are no short forms for these options. The default set-
+ tings are specified when the PCRE library is compiled, with
the default default being 10 million.
-M, --multiline
- Allow patterns to match more than one line. When this option
+ Allow patterns to match more than one line. When this option
is given, patterns may usefully contain literal newline char-
- acters and internal occurrences of ^ and $ characters. The
- output for a successful match may consist of more than one
- line, the last of which is the one in which the match ended.
+ acters and internal occurrences of ^ and $ characters. The
+ output for a successful match may consist of more than one
+ line, the last of which is the one in which the match ended.
If the matched string ends with a newline sequence the output
ends at the end of that line.
- When this option is set, the PCRE library is called in "mul-
- tiline" mode. There is a limit to the number of lines that
- can be matched, imposed by the way that pcregrep buffers the
- input file as it scans it. However, pcregrep ensures that at
+ When this option is set, the PCRE library is called in "mul-
+ tiline" mode. There is a limit to the number of lines that
+ can be matched, imposed by the way that pcregrep buffers the
+ input file as it scans it. However, pcregrep ensures that at
least 8K characters or the rest of the document (whichever is
- the shorter) are available for forward matching, and simi-
+ the shorter) are available for forward matching, and simi-
larly the previous 8K characters (or all the previous charac-
- ters, if fewer than 8K) are guaranteed to be available for
- lookbehind assertions. This option does not work when input
+ ters, if fewer than 8K) are guaranteed to be available for
+ lookbehind assertions. This option does not work when input
is read line by line (see --line-buffered.)
-N newline-type, --newline=newline-type
- The PCRE library supports five different conventions for
- indicating the ends of lines. They are the single-character
- sequences CR (carriage return) and LF (linefeed), the two-
- character sequence CRLF, an "anycrlf" convention, which rec-
- ognizes any of the preceding three types, and an "any" con-
+ The PCRE library supports five different conventions for
+ indicating the ends of lines. They are the single-character
+ sequences CR (carriage return) and LF (linefeed), the two-
+ character sequence CRLF, an "anycrlf" convention, which rec-
+ ognizes any of the preceding three types, and an "any" con-
vention, in which any Unicode line ending sequence is assumed
- to end a line. The Unicode sequences are the three just men-
- tioned, plus VT (vertical tab, U+000B), FF (formfeed,
- U+000C), NEL (next line, U+0085), LS (line separator,
+ to end a line. The Unicode sequences are the three just men-
+ tioned, plus VT (vertical tab, U+000B), FF (form feed,
+ U+000C), NEL (next line, U+0085), LS (line separator,
U+2028), and PS (paragraph separator, U+2029).
When the PCRE library is built, a default line-ending
- sequence is specified. This is normally the standard
+ sequence is specified. This is normally the standard
sequence for the operating system. Unless otherwise specified
- by this option, pcregrep uses the library's default. The
+ by this option, pcregrep uses the library's default. The
possible values for this option are CR, LF, CRLF, ANYCRLF, or
- ANY. This makes it possible to use pcregrep on files that
- have come from other environments without having to modify
- their line endings. If the data that is being scanned does
- not agree with the convention set by this option, pcregrep
+ ANY. This makes it possible to use pcregrep on files that
+ have come from other environments without having to modify
+ their line endings. If the data that is being scanned does
+ not agree with the convention set by this option, pcregrep
may behave in strange ways.
-n, --line-number
Precede each output line by its line number in the file, fol-
- lowed by a colon for matching lines or a hyphen for context
- lines. If the filename is also being output, it precedes the
+ lowed by a colon for matching lines or a hyphen for context
+ lines. If the filename is also being output, it precedes the
line number. This option is forced if --line-offsets is used.
+ --no-jit If the PCRE library is built with support for just-in-time
+ compiling (which speeds up matching), pcregrep automatically
+ makes use of this, unless it was explicitly disabled at build
+ time. This option can be used to disable the use of JIT at
+ run time. It is provided for testing and working round prob-
+ lems. It should never be needed in normal use.
+
-o, --only-matching
Show only the part of the line that matched a pattern instead
of the whole line. In this mode, no context is shown. That
@@ -521,12 +580,12 @@
OPTIONS COMPATIBILITY
Many of the short and long forms of pcregrep's options are the same as
- in the GNU grep program (version 2.5.4). Any long option of the form
- --xxx-regexp (GNU terminology) is also available as --xxx-regex (PCRE
- terminology). However, the --file-offsets, --include-dir, --line-off-
- sets, --locale, --match-limit, -M, --multiline, -N, --newline, --recur-
- sion-limit, -u, and --utf-8 options are specific to pcregrep, as is the
- use of the --only-matching option with a capturing parentheses number.
+ in the GNU grep program. Any long option of the form --xxx-regexp (GNU
+ terminology) is also available as --xxx-regex (PCRE terminology). How-
+ ever, the --file-list, --file-offsets, --include-dir, --line-offsets,
+ --locale, --match-limit, -M, --multiline, -N, --newline, --recursion-
+ limit, -u, and --utf-8 options are specific to pcregrep, as is the use
+ of the --only-matching option with a capturing parentheses number.
Although most of the common options work the same way, a few are dif-
ferent in pcregrep. For example, the --include option's argument is a
@@ -587,10 +646,10 @@
DIAGNOSTICS
Exit status is 0 if any matches were found, 1 if no matches were found,
- and 2 for syntax errors and non-existent or inacessible files (even if
- matches were found in other files) or too many matching errors. Using
- the -s option to suppress error messages about inaccessble files does
- not affect the return code.
+ and 2 for syntax errors, overlong lines, non-existent or inaccessible
+ files (even if matches were found in other files) or too many matching
+ errors. Using the -s option to suppress error messages about inaccessi-
+ ble files does not affect the return code.
SEE ALSO
@@ -607,5 +666,5 @@
REVISION
- Last updated: 14 January 2011
- Copyright (c) 1997-2011 University of Cambridge.
+ Last updated: 04 March 2012
+ Copyright (c) 1997-2012 University of Cambridge.
diff -Nru pcre3-8.12/doc/pcrejit.3 pcre3-8.31/doc/pcrejit.3
--- pcre3-8.12/doc/pcrejit.3 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/pcrejit.3 2012-06-02 10:55:17.000000000 +0000
@@ -0,0 +1,403 @@
+.TH PCREJIT 3 "04 May 2012" "PCRE 8.31"
+.SH NAME
+PCRE - Perl-compatible regular expressions
+.SH "PCRE JUST-IN-TIME COMPILER SUPPORT"
+.rs
+.sp
+Just-in-time compiling is a heavyweight optimization that can greatly speed up
+pattern matching. However, it comes at the cost of extra processing before the
+match is performed. Therefore, it is of most benefit when the same pattern is
+going to be matched many times. This does not necessarily mean many calls of a
+matching function; if the pattern is not anchored, matching attempts may take
+place many times at various positions in the subject, even for a single call.
+Therefore, if the subject string is very long, it may still pay to use JIT for
+one-off matches.
+.P
+JIT support applies only to the traditional Perl-compatible matching function.
+It does not apply when the DFA matching function is being used. The code for
+this support was written by Zoltan Herczeg.
+.
+.
+.SH "8-BIT and 16-BIT SUPPORT"
+.rs
+.sp
+JIT support is available for both the 8-bit and 16-bit PCRE libraries. To keep
+this documentation simple, only the 8-bit interface is described in what
+follows. If you are using the 16-bit library, substitute the 16-bit functions
+and 16-bit structures (for example, \fIpcre16_jit_stack\fP instead of
+\fIpcre_jit_stack\fP).
+.
+.
+.SH "AVAILABILITY OF JIT SUPPORT"
+.rs
+.sp
+JIT support is an optional feature of PCRE. The "configure" option --enable-jit
+(or equivalent CMake option) must be set when PCRE is built if you want to use
+JIT. The support is limited to the following hardware platforms:
+.sp
+ ARM v5, v7, and Thumb2
+ Intel x86 32-bit and 64-bit
+ MIPS 32-bit
+ Power PC 32-bit and 64-bit
+.sp
+If --enable-jit is set on an unsupported platform, compilation fails.
+.P
+A program that is linked with PCRE 8.20 or later can tell if JIT support is
+available by calling \fBpcre_config()\fP with the PCRE_CONFIG_JIT option. The
+result is 1 when JIT is available, and 0 otherwise. However, a simple program
+does not need to check this in order to use JIT. The API is implemented in a
+way that falls back to the interpretive code if JIT is not available.
+.P
+If your program may sometimes be linked with versions of PCRE that are older
+than 8.20, but you want to use JIT when it is available, you can test
+the values of PCRE_MAJOR and PCRE_MINOR, or the existence of a JIT macro such
+as PCRE_CONFIG_JIT, for compile-time control of your code.
+.
+.
+.SH "SIMPLE USE OF JIT"
+.rs
+.sp
+You have to do two things to make use of the JIT support in the simplest way:
+.sp
+ (1) Call \fBpcre_study()\fP with the PCRE_STUDY_JIT_COMPILE option for
+ each compiled pattern, and pass the resulting \fBpcre_extra\fP block to
+ \fBpcre_exec()\fP.
+.sp
+ (2) Use \fBpcre_free_study()\fP to free the \fBpcre_extra\fP block when it is
+ no longer needed, instead of just freeing it yourself. This
+ ensures that any JIT data is also freed.
+.sp
+For a program that may be linked with pre-8.20 versions of PCRE, you can insert
+.sp
+ #ifndef PCRE_STUDY_JIT_COMPILE
+ #define PCRE_STUDY_JIT_COMPILE 0
+ #endif
+.sp
+so that no option is passed to \fBpcre_study()\fP, and then use something like
+this to free the study data:
+.sp
+ #ifdef PCRE_CONFIG_JIT
+ pcre_free_study(study_ptr);
+ #else
+ pcre_free(study_ptr);
+ #endif
+.sp
+PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for complete
+matches. If you want to run partial matches using the PCRE_PARTIAL_HARD or
+PCRE_PARTIAL_SOFT options of \fBpcre_exec()\fP, you should set one or both of
+the following options in addition to, or instead of, PCRE_STUDY_JIT_COMPILE
+when you call \fBpcre_study()\fP:
+.sp
+ PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
+ PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
+.sp
+The JIT compiler generates different optimized code for each of the three
+modes (normal, soft partial, hard partial). When \fBpcre_exec()\fP is called,
+the appropriate code is run if it is available. Otherwise, the pattern is
+matched using interpretive code.
+.P
+In some circumstances you may need to call additional functions. These are
+described in the section entitled
+.\" HTML
+.\"
+"Controlling the JIT stack"
+.\"
+below.
+.P
+If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are ignored, and
+no JIT data is created. Otherwise, the compiled pattern is passed to the JIT
+compiler, which turns it into machine code that executes much faster than the
+normal interpretive code. When \fBpcre_exec()\fP is passed a \fBpcre_extra\fP
+block containing a pointer to JIT code of the appropriate mode (normal or
+hard/soft partial), it obeys that code instead of running the interpreter. The
+result is identical, but the compiled JIT code runs much faster.
+.P
+There are some \fBpcre_exec()\fP options that are not supported for JIT
+execution. There are also some pattern items that JIT cannot handle. Details
+are given below. In both cases, execution automatically falls back to the
+interpretive code. If you want to know whether JIT was actually used for a
+particular match, you should arrange for a JIT callback function to be set up
+as described in the section entitled
+.\" HTML
+.\"
+"Controlling the JIT stack"
+.\"
+below, even if you do not need to supply a non-default JIT stack. Such a
+callback function is called whenever JIT code is about to be obeyed. If the
+execution options are not right for JIT execution, the callback function is not
+obeyed.
+.P
+If the JIT compiler finds an unsupported item, no JIT data is generated. You
+can find out if JIT execution is available after studying a pattern by calling
+\fBpcre_fullinfo()\fP with the PCRE_INFO_JIT option. A result of 1 means that
+JIT compilation was successful. A result of 0 means that JIT support is not
+available, or the pattern was not studied with PCRE_STUDY_JIT_COMPILE etc., or
+the JIT compiler was not able to handle the pattern.
+.P
+Once a pattern has been studied, with or without JIT, it can be used as many
+times as you like for matching different subject strings.
+.
+.
+.SH "UNSUPPORTED OPTIONS AND PATTERN ITEMS"
+.rs
+.sp
+The only \fBpcre_exec()\fP options that are supported for JIT execution are
+PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NOTBOL, PCRE_NOTEOL,
+PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT.
+.P
+The unsupported pattern items are:
+.sp
+ \eC match a single byte; not supported in UTF-8 mode
+ (?Cn) callouts
+ (*PRUNE) )
+ (*SKIP) ) backtracking control verbs
+ (*THEN) )
+.sp
+Support for some of these may be added in future.
+.
+.
+.SH "RETURN VALUES FROM JIT EXECUTION"
+.rs
+.sp
+When a pattern is matched using JIT execution, the return values are the same
+as those given by the interpretive \fBpcre_exec()\fP code, with the addition of
+one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means that the memory used
+for the JIT stack was insufficient. See
+.\" HTML
+.\"
+"Controlling the JIT stack"
+.\"
+below for a discussion of JIT stack usage. For compatibility with the
+interpretive \fBpcre_exec()\fP code, no more than two-thirds of the
+\fIovector\fP argument is used for passing back captured substrings.
+.P
+The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if searching a
+very large pattern tree goes on for too long, as it is in the same circumstance
+when JIT is not used, but the details of exactly what is counted are not the
+same. The PCRE_ERROR_RECURSIONLIMIT error code is never returned by JIT
+execution.
+.
+.
+.SH "SAVING AND RESTORING COMPILED PATTERNS"
+.rs
+.sp
+The code that is generated by the JIT compiler is architecture-specific, and is
+also position dependent. For those reasons it cannot be saved (in a file or
+database) and restored later like the bytecode and other data of a compiled
+pattern. Saving and restoring compiled patterns is not something many people
+do. More detail about this facility is given in the
+.\" HREF
+\fBpcreprecompile\fP
+.\"
+documentation. It should be possible to run \fBpcre_study()\fP on a saved and
+restored pattern, and thereby recreate the JIT data, but because JIT
+compilation uses significant resources, it is probably not worth doing this;
+you might as well recompile the original pattern.
+.
+.
+.\" HTML
+.SH "CONTROLLING THE JIT STACK"
+.rs
+.sp
+When the compiled JIT code runs, it needs a block of memory to use as a stack.
+By default, it uses 32K on the machine stack. However, some large or
+complicated patterns need more than this. The error PCRE_ERROR_JIT_STACKLIMIT
+is given when there is not enough stack. Three functions are provided for
+managing blocks of memory for use as JIT stacks. There is further discussion
+about the use of JIT stacks in the section entitled
+.\" HTML
+.\"
+"JIT stack FAQ"
+.\"
+below.
+.P
+The \fBpcre_jit_stack_alloc()\fP function creates a JIT stack. Its arguments
+are a starting size and a maximum size, and it returns a pointer to an opaque
+structure of type \fBpcre_jit_stack\fP, or NULL if there is an error. The
+\fBpcre_jit_stack_free()\fP function can be used to free a stack that is no
+longer needed. (For the technically minded: the address space is allocated by
+mmap or VirtualAlloc.)
+.P
+JIT uses far less memory for recursion than the interpretive code,
+and a maximum stack size of 512K to 1M should be more than enough for any
+pattern.
+.P
+The \fBpcre_assign_jit_stack()\fP function specifies which stack JIT code
+should use. Its arguments are as follows:
+.sp
+ pcre_extra *extra
+ pcre_jit_callback callback
+ void *data
+.sp
+The \fIextra\fP argument must be the result of studying a pattern with
+PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the other
+two options:
+.sp
+ (1) If \fIcallback\fP is NULL and \fIdata\fP is NULL, an internal 32K block
+ on the machine stack is used.
+.sp
+ (2) If \fIcallback\fP is NULL and \fIdata\fP is not NULL, \fIdata\fP must be
+ a valid JIT stack, the result of calling \fBpcre_jit_stack_alloc()\fP.
+.sp
+ (3) If \fIcallback\fP is not NULL, it must point to a function that is
+ called with \fIdata\fP as an argument at the start of matching, in
+ order to set up a JIT stack. If the return from the callback
+ function is NULL, the internal 32K stack is used; otherwise the
+ return value must be a valid JIT stack, the result of calling
+ \fBpcre_jit_stack_alloc()\fP.
+.sp
+A callback function is obeyed whenever JIT code is about to be run; it is not
+obeyed when \fBpcre_exec()\fP is called with options that are incompatible for
+JIT execution. A callback function can therefore be used to determine whether a
+match operation was executed by JIT or by the interpreter.
+.P
+You may safely use the same JIT stack for more than one pattern (either by
+assigning directly or by callback), as long as the patterns are all matched
+sequentially in the same thread. In a multithread application, if you do not
+specify a JIT stack, or if you assign or pass back NULL from a callback, that
+is thread-safe, because each thread has its own machine stack. However, if you
+assign or pass back a non-NULL JIT stack, this must be a different stack for
+each thread so that the application is thread-safe.
+.P
+Strictly speaking, even more is allowed. You can assign the same non-NULL stack
+to any number of patterns as long as they are not used for matching by multiple
+threads at the same time. For example, you can assign the same stack to all
+compiled patterns, and use a global mutex in the callback to wait until the
+stack is available for use. However, this is an inefficient solution, and not
+recommended.
+.P
+This is a suggestion for how a multithreaded program that needs to set up
+non-default JIT stacks might operate:
+.sp
+ During thread initalization
+ thread_local_var = pcre_jit_stack_alloc(...)
+.sp
+ During thread exit
+ pcre_jit_stack_free(thread_local_var)
+.sp
+ Use a one-line callback function
+ return thread_local_var
+.sp
+All the functions described in this section do nothing if JIT is not available,
+and \fBpcre_assign_jit_stack()\fP does nothing unless the \fBextra\fP argument
+is non-NULL and points to a \fBpcre_extra\fP block that is the result of a
+successful study with PCRE_STUDY_JIT_COMPILE etc.
+.
+.
+.\" HTML
+.SH "JIT STACK FAQ"
+.rs
+.sp
+(1) Why do we need JIT stacks?
+.sp
+PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack where
+the local data of the current node is pushed before checking its child nodes.
+Allocating real machine stack on some platforms is difficult. For example, the
+stack chain needs to be updated every time if we extend the stack on PowerPC.
+Although it is possible, its updating time overhead decreases performance. So
+we do the recursion in memory.
+.P
+(2) Why don't we simply allocate blocks of memory with \fBmalloc()\fP?
+.sp
+Modern operating systems have a nice feature: they can reserve an address space
+instead of allocating memory. We can safely allocate memory pages inside this
+address space, so the stack could grow without moving memory data (this is
+important because of pointers). Thus we can allocate 1M address space, and use
+only a single memory page (usually 4K) if that is enough. However, we can still
+grow up to 1M anytime if needed.
+.P
+(3) Who "owns" a JIT stack?
+.sp
+The owner of the stack is the user program, not the JIT studied pattern or
+anything else. The user program must ensure that if a stack is used by
+\fBpcre_exec()\fP, (that is, it is assigned to the pattern currently running),
+that stack must not be used by any other threads (to avoid overwriting the same
+memory area). The best practice for multithreaded programs is to allocate a
+stack for each thread, and return this stack through the JIT callback function.
+.P
+(4) When should a JIT stack be freed?
+.sp
+You can free a JIT stack at any time, as long as it will not be used by
+\fBpcre_exec()\fP again. When you assign the stack to a pattern, only a pointer
+is set. There is no reference counting or any other magic. You can free the
+patterns and stacks in any order, anytime. Just \fIdo not\fP call
+\fBpcre_exec()\fP with a pattern pointing to an already freed stack, as that
+will cause SEGFAULT. (Also, do not free a stack currently used by
+\fBpcre_exec()\fP in another thread). You can also replace the stack for a
+pattern at any time. You can even free the previous stack before assigning a
+replacement.
+.P
+(5) Should I allocate/free a stack every time before/after calling
+\fBpcre_exec()\fP?
+.sp
+No, because this is too costly in terms of resources. However, you could
+implement some clever idea which release the stack if it is not used in let's
+say two minutes. The JIT callback can help to achive this without keeping a
+list of the currently JIT studied patterns.
+.P
+(6) OK, the stack is for long term memory allocation. But what happens if a
+pattern causes stack overflow with a stack of 1M? Is that 1M kept until the
+stack is freed?
+.sp
+Especially on embedded sytems, it might be a good idea to release memory
+sometimes without freeing the stack. There is no API for this at the moment.
+Probably a function call which returns with the currently allocated memory for
+any stack and another which allows releasing memory (shrinking the stack) would
+be a good idea if someone needs this.
+.P
+(7) This is too much of a headache. Isn't there any better solution for JIT
+stack handling?
+.sp
+No, thanks to Windows. If POSIX threads were used everywhere, we could throw
+out this complicated API.
+.
+.
+.SH "EXAMPLE CODE"
+.rs
+.sp
+This is a single-threaded example that specifies a JIT stack without using a
+callback.
+.sp
+ int rc;
+ int ovector[30];
+ pcre *re;
+ pcre_extra *extra;
+ pcre_jit_stack *jit_stack;
+.sp
+ re = pcre_compile(pattern, 0, &error, &erroffset, NULL);
+ /* Check for errors */
+ extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &error);
+ jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024);
+ /* Check for error (NULL) */
+ pcre_assign_jit_stack(extra, NULL, jit_stack);
+ rc = pcre_exec(re, extra, subject, length, 0, 0, ovector, 30);
+ /* Check results */
+ pcre_free(re);
+ pcre_free_study(extra);
+ pcre_jit_stack_free(jit_stack);
+.sp
+.
+.
+.SH "SEE ALSO"
+.rs
+.sp
+\fBpcreapi\fP(3)
+.
+.
+.SH AUTHOR
+.rs
+.sp
+.nf
+Philip Hazel (FAQ by Zoltan Herczeg)
+University Computing Service
+Cambridge CB2 3QH, England.
+.fi
+.
+.
+.SH REVISION
+.rs
+.sp
+.nf
+Last updated: 04 May 2012
+Copyright (c) 1997-2012 University of Cambridge.
+.fi
diff -Nru pcre3-8.12/doc/pcrelimits.3 pcre3-8.31/doc/pcrelimits.3
--- pcre3-8.12/doc/pcrelimits.3 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/doc/pcrelimits.3 2012-05-04 13:02:38.000000000 +0000
@@ -0,0 +1,66 @@
+.TH PCRELIMITS 3 "04 May 2012" "PCRE 8.30"
+.SH NAME
+PCRE - Perl-compatible regular expressions
+.SH "SIZE AND OTHER LIMITATIONS"
+.rs
+.sp
+There are some size limitations in PCRE but it is hoped that they will never in
+practice be relevant.
+.P
+The maximum length of a compiled pattern is approximately 64K data units (bytes
+for the 8-bit library, 16-bit units for the 16-bit library) if PCRE is compiled
+with the default internal linkage size of 2 bytes. If you want to process
+regular expressions that are truly enormous, you can compile PCRE with an
+internal linkage size of 3 or 4 (when building the 16-bit library, 3 is rounded
+up to 4). See the \fBREADME\fP file in the source distribution and the
+.\" HREF
+\fBpcrebuild\fP
+.\"
+documentation for details. In these cases the limit is substantially larger.
+However, the speed of execution is slower.
+.P
+All values in repeating quantifiers must be less than 65536.
+.P
+There is no limit to the number of parenthesized subpatterns, but there can be
+no more than 65535 capturing subpatterns.
+.P
+There is a limit to the number of forward references to subsequent subpatterns
+of around 200,000. Repeated forward references with fixed upper limits, for
+example, (?2){0,100} when subpattern number 2 is to the right, are included in
+the count. There is no limit to the number of backward references.
+.P
+The maximum length of name for a named subpattern is 32 characters, and the
+maximum number of named subpatterns is 10000.
+.P
+The maximum length of a name in a (*MARK), (*PRUNE), (*SKIP), or (*THEN) verb
+is 255 for the 8-bit library and 65535 for the 16-bit library.
+.P
+The maximum length of a subject string is the largest positive number that an
+integer variable can hold. However, when using the traditional matching
+function, PCRE uses recursion to handle subpatterns and indefinite repetition.
+This means that the available stack space may limit the size of a subject
+string that can be processed by certain patterns. For a discussion of stack
+issues, see the
+.\" HREF
+\fBpcrestack\fP
+.\"
+documentation.
+.
+.
+.SH AUTHOR
+.rs
+.sp
+.nf
+Philip Hazel
+University Computing Service
+Cambridge CB2 3QH, England.
+.fi
+.
+.
+.SH REVISION
+.rs
+.sp
+.nf
+Last updated: 04 May 2012
+Copyright (c) 1997-2012 University of Cambridge.
+.fi
diff -Nru pcre3-8.12/doc/pcrematching.3 pcre3-8.31/doc/pcrematching.3
--- pcre3-8.12/doc/pcrematching.3 2010-11-24 17:38:33.000000000 +0000
+++ pcre3-8.31/doc/pcrematching.3 2012-03-31 18:02:00.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCREMATCHING 3
+.TH PCREMATCHING 3 "08 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PCRE MATCHING ALGORITHMS"
@@ -6,14 +6,19 @@
.sp
This document describes the two different algorithms that are available in PCRE
for matching a compiled regular expression against a given subject string. The
-"standard" algorithm is the one provided by the \fBpcre_exec()\fP function.
-This works in the same was as Perl's matching function, and provides a
-Perl-compatible matching operation.
-.P
-An alternative algorithm is provided by the \fBpcre_dfa_exec()\fP function;
-this operates in a different way, and is not Perl-compatible. It has advantages
-and disadvantages compared with the standard algorithm, and these are described
-below.
+"standard" algorithm is the one provided by the \fBpcre_exec()\fP and
+\fBpcre16_exec()\fP functions. These work in the same was as Perl's matching
+function, and provide a Perl-compatible matching operation. The just-in-time
+(JIT) optimization that is described in the
+.\" HREF
+\fBpcrejit\fP
+.\"
+documentation is compatible with these functions.
+.P
+An alternative algorithm is provided by the \fBpcre_dfa_exec()\fP and
+\fBpcre16_dfa_exec()\fP functions; they operate in a different way, and are not
+Perl-compatible. This alternative has advantages and disadvantages compared
+with the standard algorithm, and these are described below.
.P
When there is only one possible way in which a given subject string can match a
pattern, the two algorithms give the same answer. A difference arises, however,
@@ -28,6 +33,7 @@
there are three possible answers. The standard algorithm finds only one of
them, whereas the alternative algorithm finds all three.
.
+.
.SH "REGULAR EXPRESSIONS AS TREES"
.rs
.sp
@@ -38,6 +44,7 @@
There are two ways to search a tree: depth-first and breadth-first, and these
correspond to the two matching algorithms provided by PCRE.
.
+.
.SH "THE STANDARD MATCHING ALGORITHM"
.rs
.sp
@@ -63,6 +70,7 @@
matched by portions of the pattern in parentheses. This provides support for
capturing parentheses and back references.
.
+.
.SH "THE ALTERNATIVE MATCHING ALGORITHM"
.rs
.sp
@@ -131,14 +139,15 @@
6. Callouts are supported, but the value of the \fIcapture_top\fP field is
always 1, and the value of the \fIcapture_last\fP field is always -1.
.P
-7. The \eC escape sequence, which (in the standard algorithm) matches a single
-byte, even in UTF-8 mode, is not supported because the alternative algorithm
-moves through the subject string one character at a time, for all active paths
-through the tree.
+7. The \eC escape sequence, which (in the standard algorithm) always matches a
+single data unit, even in UTF-8 or UTF-16 modes, is not supported in these
+modes, because the alternative algorithm moves through the subject string one
+character (not data unit) at a time, for all active paths through the tree.
.P
8. Except for (*FAIL), the backtracking control verbs such as (*PRUNE) are not
supported. (*FAIL) is supported, and behaves like a failing negative assertion.
.
+.
.SH "ADVANTAGES OF THE ALTERNATIVE ALGORITHM"
.rs
.sp
@@ -150,11 +159,11 @@
callouts.
.P
2. Because the alternative algorithm scans the subject string just once, and
-never needs to backtrack, it is possible to pass very long subject strings to
-the matching function in several pieces, checking for partial matching each
-time. Although it is possible to do multi-segment matching using the standard
-algorithm (\fBpcre_exec()\fP), by retaining partially matched substrings, it is
-more complicated. The
+never needs to backtrack (except for lookbehinds), it is possible to pass very
+long subject strings to the matching function in several pieces, checking for
+partial matching each time. Although it is possible to do multi-segment
+matching using the standard algorithm by retaining partially matched
+substrings, it is more complicated. The
.\" HREF
\fBpcrepartial\fP
.\"
@@ -191,6 +200,6 @@
.rs
.sp
.nf
-Last updated: 17 November 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 08 January 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcrepartial.3 pcre3-8.31/doc/pcrepartial.3
--- pcre3-8.12/doc/pcrepartial.3 2010-11-24 17:38:33.000000000 +0000
+++ pcre3-8.31/doc/pcrepartial.3 2012-06-02 10:55:17.000000000 +0000
@@ -1,14 +1,14 @@
-.TH PCREPARTIAL 3
+.TH PCREPARTIAL 3 "24 February 2012" "PCRE 8.31"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PARTIAL MATCHING IN PCRE"
.rs
.sp
-In normal use of PCRE, if the subject string that is passed to
-\fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP matches as far as it goes, but is
-too short to match the entire pattern, PCRE_ERROR_NOMATCH is returned. There
-are circumstances where it might be helpful to distinguish this case from other
-cases in which there is no match.
+In normal use of PCRE, if the subject string that is passed to a matching
+function matches as far as it goes, but is too short to match the entire
+pattern, PCRE_ERROR_NOMATCH is returned. There are circumstances where it might
+be helpful to distinguish this case from other cases in which there is no
+match.
.P
Consider, for example, an application where a human is required to type in data
for a field with specific formatting requirements. An example might be a date
@@ -25,40 +25,50 @@
long and is not all available at once.
.P
PCRE supports partial matching by means of the PCRE_PARTIAL_SOFT and
-PCRE_PARTIAL_HARD options, which can be set when calling \fBpcre_exec()\fP or
-\fBpcre_dfa_exec()\fP. For backwards compatibility, PCRE_PARTIAL is a synonym
-for PCRE_PARTIAL_SOFT. The essential difference between the two options is
-whether or not a partial match is preferred to an alternative complete match,
-though the details differ between the two matching functions. If both options
+PCRE_PARTIAL_HARD options, which can be set when calling any of the matching
+functions. For backwards compatibility, PCRE_PARTIAL is a synonym for
+PCRE_PARTIAL_SOFT. The essential difference between the two options is whether
+or not a partial match is preferred to an alternative complete match, though
+the details differ between the two types of matching function. If both options
are set, PCRE_PARTIAL_HARD takes precedence.
.P
-Setting a partial matching option disables two of PCRE's optimizations. PCRE
-remembers the last literal byte in a pattern, and abandons matching immediately
-if such a byte is not present in the subject string. This optimization cannot
-be used for a subject string that might match only partially. If the pattern
-was studied, PCRE knows the minimum length of a matching string, and does not
-bother to run the matching function on shorter strings. This optimization is
-also disabled for partial matching.
-.
-.
-.SH "PARTIAL MATCHING USING pcre_exec()"
-.rs
-.sp
-A partial match occurs during a call to \fBpcre_exec()\fP when the end of the
-subject string is reached successfully, but matching cannot continue because
-more characters are needed. However, at least one character in the subject must
-have been inspected. This character need not form part of the final matched
-string; lookbehind assertions and the \eK escape sequence provide ways of
-inspecting characters before the start of a matched substring. The requirement
-for inspecting at least one character exists because an empty string can always
-be matched; without such a restriction there would always be a partial match of
-an empty string at the end of the subject.
-.P
-If there are at least two slots in the offsets vector when \fBpcre_exec()\fP
-returns with a partial match, the first slot is set to the offset of the
-earliest character that was inspected when the partial match was found. For
-convenience, the second offset points to the end of the subject so that a
-substring can easily be identified.
+If you want to use partial matching with just-in-time optimized code, you must
+call \fBpcre_study()\fP or \fBpcre16_study()\fP with one or both of these
+options:
+.sp
+ PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
+ PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
+.sp
+PCRE_STUDY_JIT_COMPILE should also be set if you are going to run non-partial
+matches on the same pattern. If the appropriate JIT study mode has not been set
+for a match, the interpretive matching code is used.
+.P
+Setting a partial matching option disables two of PCRE's standard
+optimizations. PCRE remembers the last literal data unit in a pattern, and
+abandons matching immediately if it is not present in the subject string. This
+optimization cannot be used for a subject string that might match only
+partially. If the pattern was studied, PCRE knows the minimum length of a
+matching string, and does not bother to run the matching function on shorter
+strings. This optimization is also disabled for partial matching.
+.
+.
+.SH "PARTIAL MATCHING USING pcre_exec() OR pcre16_exec()"
+.rs
+.sp
+A partial match occurs during a call to \fBpcre_exec()\fP or
+\fBpcre16_exec()\fP when the end of the subject string is reached successfully,
+but matching cannot continue because more characters are needed. However, at
+least one character in the subject must have been inspected. This character
+need not form part of the final matched string; lookbehind assertions and the
+\eK escape sequence provide ways of inspecting characters before the start of a
+matched substring. The requirement for inspecting at least one character exists
+because an empty string can always be matched; without such a restriction there
+would always be a partial match of an empty string at the end of the subject.
+.P
+If there are at least two slots in the offsets vector when a partial match is
+returned, the first slot is set to the offset of the earliest character that
+was inspected. For convenience, the second offset points to the end of the
+subject so that a substring can easily be identified.
.P
For the majority of patterns, the first offset identifies the start of the
partially matched string. However, for patterns that contain lookbehind
@@ -76,13 +86,14 @@
partial matching options are set.
.
.
-.SS "PCRE_PARTIAL_SOFT with pcre_exec()"
+.SS "PCRE_PARTIAL_SOFT WITH pcre_exec() OR pcre16_exec()"
.rs
.sp
-If PCRE_PARTIAL_SOFT is set when \fBpcre_exec()\fP identifies a partial match,
-the partial match is remembered, but matching continues as normal, and other
-alternatives in the pattern are tried. If no complete match can be found,
-\fBpcre_exec()\fP returns PCRE_ERROR_PARTIAL instead of PCRE_ERROR_NOMATCH.
+If PCRE_PARTIAL_SOFT is set when \fBpcre_exec()\fP or \fBpcre16_exec()\fP
+identifies a partial match, the partial match is remembered, but matching
+continues as normal, and other alternatives in the pattern are tried. If no
+complete match can be found, PCRE_ERROR_PARTIAL is returned instead of
+PCRE_ERROR_NOMATCH.
.P
This option is "soft" because it prefers a complete match over a partial match.
All the various matching items in a pattern behave as if the subject string is
@@ -103,21 +114,24 @@
matches the second alternative.)
.
.
-.SS "PCRE_PARTIAL_HARD with pcre_exec()"
+.SS "PCRE_PARTIAL_HARD WITH pcre_exec() OR pcre16_exec()"
.rs
.sp
-If PCRE_PARTIAL_HARD is set for \fBpcre_exec()\fP, it returns
-PCRE_ERROR_PARTIAL as soon as a partial match is found, without continuing to
-search for possible complete matches. This option is "hard" because it prefers
-an earlier partial match over a later complete match. For this reason, the
-assumption is made that the end of the supplied subject string may not be the
-true end of the available data, and so, if \ez, \eZ, \eb, \eB, or $ are
-encountered at the end of the subject, the result is PCRE_ERROR_PARTIAL.
-.P
-Setting PCRE_PARTIAL_HARD also affects the way \fBpcre_exec()\fP checks UTF-8
-subject strings for validity. Normally, an invalid UTF-8 sequence causes the
-error PCRE_ERROR_BADUTF8. However, in the special case of a truncated UTF-8
-character at the end of the subject, PCRE_ERROR_SHORTUTF8 is returned when
+If PCRE_PARTIAL_HARD is set for \fBpcre_exec()\fP or \fBpcre16_exec()\fP,
+PCRE_ERROR_PARTIAL is returned as soon as a partial match is found, without
+continuing to search for possible complete matches. This option is "hard"
+because it prefers an earlier partial match over a later complete match. For
+this reason, the assumption is made that the end of the supplied subject string
+may not be the true end of the available data, and so, if \ez, \eZ, \eb, \eB,
+or $ are encountered at the end of the subject, the result is
+PCRE_ERROR_PARTIAL, provided that at least one character in the subject has
+been inspected.
+.P
+Setting PCRE_PARTIAL_HARD also affects the way UTF-8 and UTF-16
+subject strings are checked for validity. Normally, an invalid sequence
+causes the error PCRE_ERROR_BADUTF8 or PCRE_ERROR_BADUTF16. However, in the
+special case of a truncated character at the end of the subject,
+PCRE_ERROR_SHORTUTF8 or PCRE_ERROR_SHORTUTF16 is returned when
PCRE_PARTIAL_HARD is set.
.
.
@@ -137,25 +151,25 @@
.sp
/dog(sbody)??/
.sp
-In this case the result is always a complete match because \fBpcre_exec()\fP
-finds that first, and it never continues after finding a match. It might be
-easier to follow this explanation by thinking of the two patterns like this:
+In this case the result is always a complete match because that is found first,
+and matching never continues after finding a complete match. It might be easier
+to follow this explanation by thinking of the two patterns like this:
.sp
/dog(sbody)?/ is the same as /dogsbody|dog/
/dog(sbody)??/ is the same as /dog|dogsbody/
.sp
-The second pattern will never match "dogsbody" when \fBpcre_exec()\fP is
-used, because it will always find the shorter match first.
+The second pattern will never match "dogsbody", because it will always find the
+shorter match first.
.
.
-.SH "PARTIAL MATCHING USING pcre_dfa_exec()"
+.SH "PARTIAL MATCHING USING pcre_dfa_exec() OR pcre16_dfa_exec()"
.rs
.sp
-The \fBpcre_dfa_exec()\fP function moves along the subject string character by
-character, without backtracking, searching for all possible matches
-simultaneously. If the end of the subject is reached before the end of the
-pattern, there is the possibility of a partial match, again provided that at
-least one character has been inspected.
+The DFA functions move along the subject string character by character, without
+backtracking, searching for all possible matches simultaneously. If the end of
+the subject is reached before the end of the pattern, there is the possibility
+of a partial match, again provided that at least one character has been
+inspected.
.P
When PCRE_PARTIAL_SOFT is set, PCRE_ERROR_PARTIAL is returned only if there
have been no complete matches. Otherwise, the complete matches are returned.
@@ -164,16 +178,16 @@
partial match was found is set as the first matching string, provided there are
at least two slots in the offsets vector.
.P
-Because \fBpcre_dfa_exec()\fP always searches for all possible matches, and
-there is no difference between greedy and ungreedy repetition, its behaviour is
-different from \fBpcre_exec\fP when PCRE_PARTIAL_HARD is set. Consider the
-string "dog" matched against the ungreedy pattern shown above:
+Because the DFA functions always search for all possible matches, and there is
+no difference between greedy and ungreedy repetition, their behaviour is
+different from the standard functions when PCRE_PARTIAL_HARD is set. Consider
+the string "dog" matched against the ungreedy pattern shown above:
.sp
/dog(sbody)??/
.sp
-Whereas \fBpcre_exec()\fP stops as soon as it finds the complete match for
-"dog", \fBpcre_dfa_exec()\fP also finds the partial match for "dogsbody", and
-so returns that when PCRE_PARTIAL_HARD is set.
+Whereas the standard functions stop as soon as they find the complete match for
+"dog", the DFA functions also find the partial match for "dogsbody", and so
+return that when PCRE_PARTIAL_HARD is set.
.
.
.SH "PARTIAL MATCHING AND WORD BOUNDARIES"
@@ -187,14 +201,11 @@
.sp
This matches "cat", provided there is a word boundary at either end. If the
subject string is "the cat", the comparison of the final "t" with a following
-character cannot take place, so a partial match is found. However,
-\fBpcre_exec()\fP carries on with normal matching, which matches \eb at the end
-of the subject when the last character is a letter, thus finding a complete
-match. The result, therefore, is \fInot\fP PCRE_ERROR_PARTIAL. The same thing
-happens with \fBpcre_dfa_exec()\fP, because it also finds the complete match.
-.P
-Using PCRE_PARTIAL_HARD in this case does yield PCRE_ERROR_PARTIAL, because
-then the partial match takes precedence.
+character cannot take place, so a partial match is found. However, normal
+matching carries on, and \eb matches at the end of the subject when the last
+character is a letter, so a complete match is found. The result, therefore, is
+\fInot\fP PCRE_ERROR_PARTIAL. Using PCRE_PARTIAL_HARD in this case does yield
+PCRE_ERROR_PARTIAL, because then the partial match takes precedence.
.
.
.SH "FORMERLY RESTRICTED PATTERNS"
@@ -204,7 +215,7 @@
optimizations were implemented in the \fBpcre_exec()\fP function, the
PCRE_PARTIAL option (predecessor of PCRE_PARTIAL_SOFT) could not be used with
all patterns. From release 8.00 onwards, the restrictions no longer apply, and
-partial matching with \fBpcre_exec()\fP can be requested for any pattern.
+partial matching with can be requested for any pattern.
.P
Items that were formerly restricted were repeated single characters and
repeated metasequences. If PCRE_PARTIAL was set for a pattern that did not
@@ -237,23 +248,22 @@
The first data string is matched completely, so \fBpcretest\fP shows the
matched substrings. The remaining four strings do not match the complete
pattern, but the first two are partial matches. Similar output is obtained
-when \fBpcre_dfa_exec()\fP is used.
+if DFA matching is used.
.P
If the escape sequence \eP is present more than once in a \fBpcretest\fP data
line, the PCRE_PARTIAL_HARD option is set for the match.
.
.
-.SH "MULTI-SEGMENT MATCHING WITH pcre_dfa_exec()"
+.SH "MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre16_dfa_exec()"
.rs
.sp
-When a partial match has been found using \fBpcre_dfa_exec()\fP, it is possible
-to continue the match by providing additional subject data and calling
-\fBpcre_dfa_exec()\fP again with the same compiled regular expression, this
-time setting the PCRE_DFA_RESTART option. You must pass the same working
-space as before, because this is where details of the previous partial match
-are stored. Here is an example using \fBpcretest\fP, using the \eR escape
-sequence to set the PCRE_DFA_RESTART option (\eD specifies the use of
-\fBpcre_dfa_exec()\fP):
+When a partial match has been found using a DFA matching function, it is
+possible to continue the match by providing additional subject data and calling
+the function again with the same compiled regular expression, this time setting
+the PCRE_DFA_RESTART option. You must pass the same working space as before,
+because this is where details of the previous partial match are stored. Here is
+an example using \fBpcretest\fP, using the \eR escape sequence to set the
+PCRE_DFA_RESTART option (\eD specifies the use of the DFA matching function):
.sp
re> /^\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed$/
data> 23ja\eP\eD
@@ -269,36 +279,39 @@
.P
You can set the PCRE_PARTIAL_SOFT or PCRE_PARTIAL_HARD options with
PCRE_DFA_RESTART to continue partial matching over multiple segments. This
-facility can be used to pass very long subject strings to
-\fBpcre_dfa_exec()\fP.
+facility can be used to pass very long subject strings to the DFA matching
+functions.
.
.
-.SH "MULTI-SEGMENT MATCHING WITH pcre_exec()"
+.SH "MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre16_exec()"
.rs
.sp
-From release 8.00, \fBpcre_exec()\fP can also be used to do multi-segment
-matching. Unlike \fBpcre_dfa_exec()\fP, it is not possible to restart the
-previous match with a new segment of data. Instead, new data must be added to
-the previous subject string, and the entire match re-run, starting from the
-point where the partial match occurred. Earlier data can be discarded. It is
-best to use PCRE_PARTIAL_HARD in this situation, because it does not treat the
-end of a segment as the end of the subject when matching \ez, \eZ, \eb, \eB,
-and $. Consider an unanchored pattern that matches dates:
+From release 8.00, the standard matching functions can also be used to do
+multi-segment matching. Unlike the DFA functions, it is not possible to
+restart the previous match with a new segment of data. Instead, new data must
+be added to the previous subject string, and the entire match re-run, starting
+from the point where the partial match occurred. Earlier data can be discarded.
+.P
+It is best to use PCRE_PARTIAL_HARD in this situation, because it does not
+treat the end of a segment as the end of the subject when matching \ez, \eZ,
+\eb, \eB, and $. Consider an unanchored pattern that matches dates:
.sp
re> /\ed?\ed(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\ed\ed/
data> The date is 23ja\eP\eP
Partial match: 23ja
.sp
At this stage, an application could discard the text preceding "23ja", add on
-text from the next segment, and call \fBpcre_exec()\fP again. Unlike
-\fBpcre_dfa_exec()\fP, the entire matching string must always be available, and
-the complete matching process occurs for each call, so more memory and more
+text from the next segment, and call the matching function again. Unlike the
+DFA matching functions, the entire matching string must always be available,
+and the complete matching process occurs for each call, so more memory and more
processing time is needed.
.P
\fBNote:\fP If the pattern contains lookbehind assertions, or \eK, or starts
-with \eb or \eB, the string that is returned for a partial match will include
+with \eb or \eB, the string that is returned for a partial match includes
characters that precede the partially matched string itself, because these must
be retained when adding on more characters for a subsequent matching attempt.
+However, in some cases you may need to retain even earlier characters, as
+discussed in the next section.
.
.
.SH "ISSUES WITH MULTI-SEGMENT MATCHING"
@@ -313,14 +326,31 @@
doing multi-segment matching you should be using PCRE_PARTIAL_HARD, which
includes the effect of PCRE_NOTEOL.
.P
-2. Lookbehind assertions at the start of a pattern are catered for in the
-offsets that are returned for a partial match. However, in theory, a lookbehind
-assertion later in the pattern could require even earlier characters to be
-inspected, and it might not have been reached when a partial match occurs. This
-is probably an extremely unlikely case; you could guard against it to a certain
-extent by always including extra characters at the start.
+2. Lookbehind assertions that have already been obeyed are catered for in the
+offsets that are returned for a partial match. However a lookbehind assertion
+later in the pattern could require even earlier characters to be inspected. You
+can handle this case by using the PCRE_INFO_MAXLOOKBEHIND option of the
+\fBpcre_fullinfo()\fP or \fBpcre16_fullinfo()\fP functions to obtain the length
+of the largest lookbehind in the pattern. This length is given in characters,
+not bytes. If you always retain at least that many characters before the
+partially matched string, all should be well. (Of course, near the start of the
+subject, fewer characters may be present; in that case all characters should be
+retained.)
+.P
+3. Because a partial match must always contain at least one character, what
+might be considered a partial match of an empty string actually gives a "no
+match" result. For example:
+.sp
+ re> /c(?<=abc)x/
+ data> ab\eP
+ No match
+.sp
+If the next segment begins "cx", a match should be found, but this will only
+happen if characters from the previous segment are retained. For this reason, a
+"no match" result should be interpreted as "partial match of an empty string"
+when the pattern contains lookbehinds.
.P
-3. Matching a subject string that is split into multiple segments may not
+4. Matching a subject string that is split into multiple segments may not
always produce exactly the same result as matching over one single long string,
especially when PCRE_PARTIAL_SOFT is used. The section "Partial Matching and
Word Boundaries" above describes an issue that arises if the pattern ends with
@@ -341,14 +371,14 @@
0: dogsbody
1: dog
.sp
-The first data line passes the string "dogsb" to \fBpcre_exec()\fP, setting the
-PCRE_PARTIAL_SOFT option. Although the string is a partial match for
-"dogsbody", the result is not PCRE_ERROR_PARTIAL, because the shorter string
-"dog" is a complete match. Similarly, when the subject is presented to
-\fBpcre_dfa_exec()\fP in several parts ("do" and "gsb" being the first two) the
-match stops when "dog" has been found, and it is not possible to continue. On
-the other hand, if "dogsbody" is presented as a single string,
-\fBpcre_dfa_exec()\fP finds both matches.
+The first data line passes the string "dogsb" to a standard matching function,
+setting the PCRE_PARTIAL_SOFT option. Although the string is a partial match
+for "dogsbody", the result is not PCRE_ERROR_PARTIAL, because the shorter
+string "dog" is a complete match. Similarly, when the subject is presented to
+a DFA matching function in several parts ("do" and "gsb" being the first two)
+the match stops when "dog" has been found, and it is not possible to continue.
+On the other hand, if "dogsbody" is presented as a single string, a DFA
+matching function finds both matches.
.P
Because of these problems, it is best to use PCRE_PARTIAL_HARD when matching
multi-segment data. The example above then behaves differently:
@@ -361,10 +391,9 @@
data> gsb\eR\eP\eP\eD
Partial match: gsb
.sp
-4. Patterns that contain alternatives at the top level which do not all
-start with the same pattern item may not work as expected when
-PCRE_DFA_RESTART is used with \fBpcre_dfa_exec()\fP. For example, consider this
-pattern:
+5. Patterns that contain alternatives at the top level which do not all start
+with the same pattern item may not work as expected when PCRE_DFA_RESTART is
+used. For example, consider this pattern:
.sp
1234|3789
.sp
@@ -380,8 +409,8 @@
1234|ABCD
.sp
where no string can be a partial match for both alternatives. This is not a
-problem if \fBpcre_exec()\fP is used, because the entire match has to be rerun
-each time:
+problem if a standard matching function is used, because the entire match has
+to be rerun each time:
.sp
re> /1234|3789/
data> ABC123\eP\eP
@@ -390,7 +419,7 @@
0: 3789
.sp
Of course, instead of using PCRE_DFA_RESTART, the same technique of re-running
-the entire match can also be used with \fBpcre_dfa_exec()\fP. Another
+the entire match can also be used with the DFA matching functions. Another
possibility is to work with two buffers. If a partial match at offset \fIn\fP
in the first buffer is followed by "no match" when PCRE_DFA_RESTART is used on
the second buffer, you can then try a new match starting at offset \fIn+1\fP in
@@ -411,6 +440,6 @@
.rs
.sp
.nf
-Last updated: 07 November 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 24 February 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcrepattern.3 pcre3-8.31/doc/pcrepattern.3
--- pcre3-8.12/doc/pcrepattern.3 2010-11-24 17:38:33.000000000 +0000
+++ pcre3-8.31/doc/pcrepattern.3 2012-06-20 15:08:50.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCREPATTERN 3
+.TH PCREPATTERN 3 "04 May 2012" "PCRE 8.31"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PCRE REGULAR EXPRESSION DETAILS"
@@ -21,29 +21,27 @@
description of PCRE's regular expressions is intended as reference material.
.P
The original operation of PCRE was on strings of one-byte characters. However,
-there is now also support for UTF-8 character strings. To use this,
-PCRE must be built to include UTF-8 support, and you must call
-\fBpcre_compile()\fP or \fBpcre_compile2()\fP with the PCRE_UTF8 option. There
-is also a special sequence that can be given at the start of a pattern:
+there is now also support for UTF-8 strings in the original library, and a
+second library that supports 16-bit and UTF-16 character strings. To use these
+features, PCRE must be built to include appropriate support. When using UTF
+strings you must either call the compiling function with the PCRE_UTF8 or
+PCRE_UTF16 option, or the pattern must start with one of these special
+sequences:
.sp
(*UTF8)
+ (*UTF16)
.sp
-Starting a pattern with this sequence is equivalent to setting the PCRE_UTF8
-option. This feature is not Perl-compatible. How setting UTF-8 mode affects
+Starting a pattern with such a sequence is equivalent to setting the relevant
+option. This feature is not Perl-compatible. How setting a UTF mode affects
pattern matching is mentioned in several places below. There is also a summary
-of UTF-8 features in the
-.\" HTML
-.\"
-section on UTF-8 support
-.\"
-in the main
+of features in the
.\" HREF
-\fBpcre\fP
+\fBpcreunicode\fP
.\"
page.
.P
Another special sequence that may appear at the start of a pattern or in
-combination with (*UTF8) is:
+combination with (*UTF8) or (*UTF16) is:
.sp
(*UCP)
.sp
@@ -58,13 +56,13 @@
of newlines; they are described below.
.P
The remainder of this document discusses the patterns that are supported by
-PCRE when its main matching function, \fBpcre_exec()\fP, is used.
-From release 6.0, PCRE offers a second matching function,
-\fBpcre_dfa_exec()\fP, which matches using a different algorithm that is not
-Perl-compatible. Some of the features discussed below are not available when
-\fBpcre_dfa_exec()\fP is used. The advantages and disadvantages of the
-alternative function, and how it differs from the normal function, are
-discussed in the
+PCRE when one its main matching functions, \fBpcre_exec()\fP (8-bit) or
+\fBpcre16_exec()\fP (16-bit), is used. PCRE also has alternative matching
+functions, \fBpcre_dfa_exec()\fP and \fBpcre16_dfa_exec()\fP, which match using
+a different algorithm that is not Perl-compatible. Some of the features
+discussed below are not available when DFA matching is used. The advantages and
+disadvantages of the alternative functions, and how they differ from the normal
+functions, are discussed in the
.\" HREF
\fBpcrematching\fP
.\"
@@ -99,9 +97,8 @@
(*ANYCRLF) any of the three above
(*ANY) all Unicode newline sequences
.sp
-These override the default and the options given to \fBpcre_compile()\fP or
-\fBpcre_compile2()\fP. For example, on a Unix system where LF is the default
-newline sequence, the pattern
+These override the default and the options given to the compiling function. For
+example, on a Unix system where LF is the default newline sequence, the pattern
.sp
(*CR)a.b
.sp
@@ -135,13 +132,13 @@
.sp
matches a portion of a subject string that is identical to itself. When
caseless matching is specified (the PCRE_CASELESS option), letters are matched
-independently of case. In UTF-8 mode, PCRE always understands the concept of
+independently of case. In a UTF mode, PCRE always understands the concept of
case for characters whose values are less than 128, so caseless matching is
always possible. For characters with higher values, the concept of case is
supported if PCRE is compiled with Unicode property support, but not otherwise.
If you want to use caseless matching for characters 128 and above, you must
ensure that PCRE is compiled with Unicode property support as well as with
-UTF-8 support.
+UTF support.
.P
The power of regular expressions comes from the ability to include alternatives
and repetitions in the pattern. These are encoded in the pattern by the use of
@@ -197,14 +194,14 @@
non-alphanumeric with backslash to specify that it stands for itself. In
particular, if you want to match a backslash, you write \e\e.
.P
-In UTF-8 mode, only ASCII numbers and letters have any special meaning after a
+In a UTF mode, only ASCII numbers and letters have any special meaning after a
backslash. All other characters (in particular, those whose codepoints are
greater than 127) are treated as literals.
.P
-If a pattern is compiled with the PCRE_EXTENDED option, whitespace in the
+If a pattern is compiled with the PCRE_EXTENDED option, white space in the
pattern (other than in a character class) and characters between a # outside
a character class and the next newline are ignored. An escaping backslash can
-be used to include a whitespace or # character as part of the pattern.
+be used to include a white space or # character as part of the pattern.
.P
If you want to remove the special meaning from a sequence of characters, you
can do so by putting them between \eQ and \eE. This is different from Perl in
@@ -220,7 +217,11 @@
\eQabc\eE\e$\eQxyz\eE abc$xyz abc$xyz
.sp
The \eQ...\eE sequence is recognized both inside and outside character classes.
-An isolated \eE that is not preceded by \eQ is ignored.
+An isolated \eE that is not preceded by \eQ is ignored. If \eQ is not followed
+by \eE later in the pattern, the literal interpretation continues to the end of
+the pattern (that is, \eE is assumed at the end). If the isolated \eQ is inside
+a character class, this causes an error, because the character class is not
+terminated.
.
.
.\" HTML
@@ -236,38 +237,53 @@
\ea alarm, that is, the BEL character (hex 07)
\ecx "control-x", where x is any ASCII character
\ee escape (hex 1B)
- \ef formfeed (hex 0C)
+ \ef form feed (hex 0C)
\en linefeed (hex 0A)
\er carriage return (hex 0D)
\et tab (hex 09)
\eddd character with octal code ddd, or back reference
\exhh character with hex code hh
- \ex{hhh..} character with hex code hhh..
+ \ex{hhh..} character with hex code hhh.. (non-JavaScript mode)
+ \euhhhh character with hex code hhhh (JavaScript mode only)
.sp
The precise effect of \ecx is as follows: if x is a lower case letter, it
is converted to upper case. Then bit 6 of the character (hex 40) is inverted.
Thus \ecz becomes hex 1A (z is 7A), but \ec{ becomes hex 3B ({ is 7B), while
\ec; becomes hex 7B (; is 3B). If the byte following \ec has a value greater
than 127, a compile-time error occurs. This locks out non-ASCII characters in
-both byte mode and UTF-8 mode. (When PCRE is compiled in EBCDIC mode, all byte
-values are valid. A lower case letter is converted to upper case, and then the
-0xc0 bits are flipped.)
-.P
-After \ex, from zero to two hexadecimal digits are read (letters can be in
-upper or lower case). Any number of hexadecimal digits may appear between \ex{
-and }, but the value of the character code must be less than 256 in non-UTF-8
-mode, and less than 2**31 in UTF-8 mode. That is, the maximum value in
-hexadecimal is 7FFFFFFF. Note that this is bigger than the largest Unicode code
-point, which is 10FFFF.
+all modes. (When PCRE is compiled in EBCDIC mode, all byte values are valid. A
+lower case letter is converted to upper case, and then the 0xc0 bits are
+flipped.)
+.P
+By default, after \ex, from zero to two hexadecimal digits are read (letters
+can be in upper or lower case). Any number of hexadecimal digits may appear
+between \ex{ and }, but the character code is constrained as follows:
+.sp
+ 8-bit non-UTF mode less than 0x100
+ 8-bit UTF-8 mode less than 0x10ffff and a valid codepoint
+ 16-bit non-UTF mode less than 0x10000
+ 16-bit UTF-16 mode less than 0x10ffff and a valid codepoint
+.sp
+Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-called
+"surrogate" codepoints).
.P
If characters other than hexadecimal digits appear between \ex{ and }, or if
there is no terminating }, this form of escape is not recognized. Instead, the
initial \ex will be interpreted as a basic hexadecimal escape, with no
following digits, giving a character whose value is zero.
.P
+If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \ex is
+as just described only when it is followed by two hexadecimal digits.
+Otherwise, it matches a literal "x" character. In JavaScript mode, support for
+code points greater than 256 is provided by \eu, which must be followed by
+four hexadecimal digits; otherwise it matches a literal "u" character.
+Character codes specified by \eu in JavaScript mode are constrained in the same
+was as those specified by \ex in non-JavaScript mode.
+.P
Characters whose value is less than 256 can be defined by either of the two
-syntaxes for \ex. There is no difference in the way they are handled. For
-example, \exdc is exactly the same as \ex{dc}.
+syntaxes for \ex (or by \eu in JavaScript mode). There is no difference in the
+way they are handled. For example, \exdc is exactly the same as \ex{dc} (or
+\eu00dc in JavaScript mode).
.P
After \e0 up to two further octal digits are read. If there are fewer than two
digits, just those that are present are used. Thus the sequence \e0\ex\e07
@@ -293,9 +309,9 @@
Inside a character class, or if the decimal number is greater than 9 and there
have not been that many capturing subpatterns, PCRE re-reads up to three octal
digits following the backslash, and uses them to generate a data character. Any
-subsequent digits stand for themselves. In non-UTF-8 mode, the value of a
-character specified in octal must be less than \e400. In UTF-8 mode, values up
-to \e777 are permitted. For example:
+subsequent digits stand for themselves. The value of the character is
+constrained in the same way as characters specified in hexadecimal.
+For example:
.sp
\e040 is another way of writing a space
.\" JOIN
@@ -312,7 +328,7 @@
character with octal code 113
.\" JOIN
\e377 might be a back reference, otherwise
- the byte consisting entirely of 1 bits
+ the value 255 (decimal)
.\" JOIN
\e81 is either a back reference, or a binary zero
followed by the two characters "8" and "1"
@@ -321,12 +337,24 @@
zero, because no more than three octal digits are ever read.
.P
All the sequences that define a single character value can be used both inside
-and outside character classes. In addition, inside a character class, the
-sequence \eb is interpreted as the backspace character (hex 08). The sequences
-\eB, \eN, \eR, and \eX are not special inside a character class. Like any other
-unrecognized escape sequences, they are treated as the literal characters "B",
-"N", "R", and "X" by default, but cause an error if the PCRE_EXTRA option is
-set. Outside a character class, these sequences have different meanings.
+and outside character classes. In addition, inside a character class, \eb is
+interpreted as the backspace character (hex 08).
+.P
+\eN is not allowed in a character class. \eB, \eR, and \eX are not special
+inside a character class. Like other unrecognized escape sequences, they are
+treated as the literal characters "B", "R", and "X" by default, but cause an
+error if the PCRE_EXTRA option is set. Outside a character class, these
+sequences have different meanings.
+.
+.
+.SS "Unsupported escape sequences"
+.rs
+.sp
+In Perl, the sequences \el, \eL, \eu, and \eU are recognized by its string
+handler and used to modify the case of following characters. By default, PCRE
+does not support these escape sequences. However, if the PCRE_JAVASCRIPT_COMPAT
+option is set, \eU matches a "U" character, and \eu can be used to define a
+character by code point, as described in the previous section.
.
.
.SS "Absolute and relative back references"
@@ -373,12 +401,12 @@
.sp
\ed any decimal digit
\eD any character that is not a decimal digit
- \eh any horizontal whitespace character
- \eH any character that is not a horizontal whitespace character
- \es any whitespace character
- \eS any character that is not a whitespace character
- \ev any vertical whitespace character
- \eV any character that is not a vertical whitespace character
+ \eh any horizontal white space character
+ \eH any character that is not a horizontal white space character
+ \es any white space character
+ \eS any character that is not a white space character
+ \ev any vertical white space character
+ \eV any character that is not a vertical white space character
\ew any "word" character
\eW any "non-word" character
.sp
@@ -388,7 +416,8 @@
.\"
the "." metacharacter
.\"
-when PCRE_DOTALL is not set.
+when PCRE_DOTALL is not set. Perl also uses \eN to match characters by name;
+PCRE does not support this.
.P
Each pair of lower and upper case escape sequences partitions the complete set
of characters into two disjoint sets. Any given character matches one, and only
@@ -420,9 +449,9 @@
accented letters, and these are then matched by \ew. The use of locales with
Unicode is discouraged.
.P
-By default, in UTF-8 mode, characters with values greater than 128 never match
+By default, in a UTF mode, characters with values greater than 128 never match
\ed, \es, or \ew, and always match \eD, \eS, and \eW. These sequences retain
-their original meanings from before UTF-8 support was available, mainly for
+their original meanings from before UTF support was available, mainly for
efficiency reasons. However, if PCRE is compiled with Unicode property support,
and the PCRE_UCP option is set, the behaviour is changed so that Unicode
properties are used to determine character types, as follows:
@@ -439,9 +468,8 @@
.P
The sequences \eh, \eH, \ev, and \eV are features that were added to Perl at
release 5.10. In contrast to the other sequences, which match only ASCII
-characters by default, these always match certain high-valued codepoints in
-UTF-8 mode, whether or not PCRE_UCP is set. The horizontal space characters
-are:
+characters by default, these always match certain high-valued codepoints,
+whether or not PCRE_UCP is set. The horizontal space characters are:
.sp
U+0009 Horizontal tab
U+0020 Space
@@ -467,11 +495,14 @@
.sp
U+000A Linefeed
U+000B Vertical tab
- U+000C Formfeed
+ U+000C Form feed
U+000D Carriage return
U+0085 Next line
U+2028 Line separator
U+2029 Paragraph separator
+.sp
+In 8-bit, non-UTF-8 mode, only the characters with codepoints less than 256 are
+relevant.
.
.
.\" HTML
@@ -479,7 +510,8 @@
.rs
.sp
Outside a character class, by default, the escape sequence \eR matches any
-Unicode newline sequence. In non-UTF-8 mode \eR is equivalent to the following:
+Unicode newline sequence. In 8-bit non-UTF-8 mode \eR is equivalent to the
+following:
.sp
(?>\er\en|\en|\ex0b|\ef|\er|\ex85)
.sp
@@ -490,11 +522,11 @@
.\"
This particular group matches either the two-character sequence CR followed by
LF, or one of the single characters LF (linefeed, U+000A), VT (vertical tab,
-U+000B), FF (formfeed, U+000C), CR (carriage return, U+000D), or NEL (next
+U+000B), FF (form feed, U+000C), CR (carriage return, U+000D), or NEL (next
line, U+0085). The two-character sequence is treated as a single unit that
cannot be split.
.P
-In UTF-8 mode, two additional characters whose codepoints are greater than 255
+In other modes, two additional characters whose codepoints are greater than 255
are added: LS (line separator, U+2028) and PS (paragraph separator, U+2029).
Unicode character property support is not needed for these characters to be
recognized.
@@ -510,19 +542,19 @@
(*BSR_ANYCRLF) CR, LF, or CRLF only
(*BSR_UNICODE) any Unicode newline sequence
.sp
-These override the default and the options given to \fBpcre_compile()\fP or
-\fBpcre_compile2()\fP, but they can be overridden by options given to
-\fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP. Note that these special settings,
-which are not Perl-compatible, are recognized only at the very start of a
-pattern, and that they must be in upper case. If more than one of them is
-present, the last one is used. They can be combined with a change of newline
-convention; for example, a pattern can start with:
+These override the default and the options given to the compiling function, but
+they can themselves be overridden by options given to a matching function. Note
+that these special settings, which are not Perl-compatible, are recognized only
+at the very start of a pattern, and that they must be in upper case. If more
+than one of them is present, the last one is used. They can be combined with a
+change of newline convention; for example, a pattern can start with:
.sp
(*ANY)(*BSR_ANYCRLF)
.sp
-They can also be combined with the (*UTF8) or (*UCP) special sequences. Inside
-a character class, \eR is treated as an unrecognized escape sequence, and so
-matches the letter "R" by default, but causes an error if PCRE_EXTRA is set.
+They can also be combined with the (*UTF8), (*UTF16), or (*UCP) special
+sequences. Inside a character class, \eR is treated as an unrecognized escape
+sequence, and so matches the letter "R" by default, but causes an error if
+PCRE_EXTRA is set.
.
.
.\" HTML
@@ -531,7 +563,7 @@
.sp
When PCRE is built with Unicode character property support, three additional
escape sequences that match characters with specific properties are available.
-When not in UTF-8 mode, these sequences are of course limited to testing
+When in 8-bit non-UTF-8 mode, these sequences are of course limited to testing
characters whose codepoints are less than 256, but they do work in this mode.
The extra escape sequences are:
.sp
@@ -566,13 +598,16 @@
Avestan,
Balinese,
Bamum,
+Batak,
Bengali,
Bopomofo,
+Brahmi,
Braille,
Buginese,
Buhid,
Canadian_Aboriginal,
Carian,
+Chakma,
Cham,
Cherokee,
Common,
@@ -615,7 +650,11 @@
Lycian,
Lydian,
Malayalam,
+Mandaic,
Meetei_Mayek,
+Meroitic_Cursive,
+Meroitic_Hieroglyphs,
+Miao,
Mongolian,
Myanmar,
New_Tai_Lue,
@@ -634,8 +673,10 @@
Runic,
Samaritan,
Saurashtra,
+Sharada,
Shavian,
Sinhala,
+Sora_Sompeng,
Sundanese,
Syloti_Nagri,
Syriac,
@@ -644,6 +685,7 @@
Tai_Le,
Tai_Tham,
Tai_Viet,
+Takri,
Tamil,
Telugu,
Thaana,
@@ -718,9 +760,9 @@
a modifier or "other".
.P
The Cs (Surrogate) property applies only to characters in the range U+D800 to
-U+DFFF. Such characters are not valid in UTF-8 strings (see RFC 3629) and so
-cannot be tested by PCRE, unless UTF-8 validity checking has been turned off
-(see the discussion of PCRE_NO_UTF8_CHECK in the
+U+DFFF. Such characters are not valid in Unicode strings and so
+cannot be tested by PCRE, unless UTF validity checking has been turned off
+(see the discussion of PCRE_NO_UTF8_CHECK and PCRE_NO_UTF16_CHECK in the
.\" HREF
\fBpcreapi\fP
.\"
@@ -751,14 +793,16 @@
.\"
Characters with the "mark" property are typically accents that affect the
preceding character. None of them have codepoints less than 256, so in
-non-UTF-8 mode \eX matches any one character.
+8-bit non-UTF-8 mode \eX matches any one character.
+.P
+Note that recent versions of Perl have changed \eX to match what Unicode calls
+an "extended grapheme cluster", which has a more complicated definition.
.P
Matching characters by Unicode property is not fast, because PCRE has to search
a structure that contains data for over fifteen thousand characters. That is
why the traditional escape sequences such as \ed and \ew do not use Unicode
properties in PCRE by default, though you can make them do so by setting the
-PCRE_UCP option for \fBpcre_compile()\fP or by starting the pattern with
-(*UCP).
+PCRE_UCP option or by starting the pattern with (*UCP).
.
.
.\" HTML
@@ -777,7 +821,7 @@
Xwd Any Perl "word" character
.sp
Xan matches characters that have either the L (letter) or the N (number)
-property. Xps matches the characters tab, linefeed, vertical tab, formfeed, or
+property. Xps matches the characters tab, linefeed, vertical tab, form feed, or
carriage return, and any other character that has the Z (separator) property.
Xsp is the same as Xps, except that vertical tab is excluded. Xwd matches the
same characters as Xan, plus underscore.
@@ -847,7 +891,7 @@
A word boundary is a position in the subject string where the current character
and the previous character do not both match \ew or \eW (i.e. one matches
\ew and the other matches \eW), or the start or end of the string if the
-first or last character matches \ew, respectively. In UTF-8 mode, the meanings
+first or last character matches \ew, respectively. In a UTF mode, the meanings
of \ew and \eW can be changed by setting the PCRE_UCP option. When this is
done, it also affects \eb and \eB. Neither PCRE nor Perl has a separate "start
of word" or "end of word" metasequence. However, whatever follows \eb normally
@@ -942,7 +986,7 @@
.sp
Outside a character class, a dot in the pattern matches any one character in
the subject string except (by default) a character that signifies the end of a
-line. In UTF-8 mode, the matched character may be more than one byte long.
+line.
.P
When a line ending is defined as a single character, dot never matches that
character; when the two-character sequence CRLF is used, dot does not match CR
@@ -962,26 +1006,53 @@
.P
The escape sequence \eN behaves like a dot, except that it is not affected by
the PCRE_DOTALL option. In other words, it matches any character except one
-that signifies the end of a line.
+that signifies the end of a line. Perl also uses \eN to match characters by
+name; PCRE does not support this.
.
.
-.SH "MATCHING A SINGLE BYTE"
+.SH "MATCHING A SINGLE DATA UNIT"
.rs
.sp
-Outside a character class, the escape sequence \eC matches any one byte, both
-in and out of UTF-8 mode. Unlike a dot, it always matches any line-ending
-characters. The feature is provided in Perl in order to match individual bytes
-in UTF-8 mode. Because it breaks up UTF-8 characters into individual bytes, the
-rest of the string may start with a malformed UTF-8 character. For this reason,
-the \eC escape sequence is best avoided.
+Outside a character class, the escape sequence \eC matches any one data unit,
+whether or not a UTF mode is set. In the 8-bit library, one data unit is one
+byte; in the 16-bit library it is a 16-bit unit. Unlike a dot, \eC always
+matches line-ending characters. The feature is provided in Perl in order to
+match individual bytes in UTF-8 mode, but it is unclear how it can usefully be
+used. Because \eC breaks up characters into individual data units, matching one
+unit with \eC in a UTF mode means that the rest of the string may start with a
+malformed UTF character. This has undefined results, because PCRE assumes that
+it is dealing with valid UTF strings (and by default it checks this at the
+start of processing unless the PCRE_NO_UTF8_CHECK or PCRE_NO_UTF16_CHECK option
+is used).
.P
PCRE does not allow \eC to appear in lookbehind assertions
.\" HTML
.\"
-(described below),
+(described below)
.\"
-because in UTF-8 mode this would make it impossible to calculate the length of
+in a UTF mode, because this would make it impossible to calculate the length of
the lookbehind.
+.P
+In general, the \eC escape sequence is best avoided. However, one
+way of using it that avoids the problem of malformed UTF characters is to use a
+lookahead to check the length of the next character, as in this pattern, which
+could be used with a UTF-8 string (ignore white space and line breaks):
+.sp
+ (?| (?=[\ex00-\ex7f])(\eC) |
+ (?=[\ex80-\ex{7ff}])(\eC)(\eC) |
+ (?=[\ex{800}-\ex{ffff}])(\eC)(\eC)(\eC) |
+ (?=[\ex{10000}-\ex{1fffff}])(\eC)(\eC)(\eC)(\eC))
+.sp
+A group that starts with (?| resets the capturing parentheses numbers in each
+alternative (see
+.\" HTML
+.\"
+"Duplicate Subpattern Numbers"
+.\"
+below). The assertions at the start of each branch check the next UTF-8
+character for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The
+character's individual bytes are then captured by the appropriate number of
+groups.
.
.
.\" HTML
@@ -995,12 +1066,12 @@
a member of the class, it should be the first data character in the class
(after an initial circumflex, if present) or escaped with a backslash.
.P
-A character class matches a single character in the subject. In UTF-8 mode, the
-character may be more than one byte long. A matched character must be in the
-set of characters defined by the class, unless the first character in the class
-definition is a circumflex, in which case the subject character must not be in
-the set defined by the class. If a circumflex is actually required as a member
-of the class, ensure it is not the first character, or escape it with a
+A character class matches a single character in the subject. In a UTF mode, the
+character may be more than one data unit long. A matched character must be in
+the set of characters defined by the class, unless the first character in the
+class definition is a circumflex, in which case the subject character must not
+be in the set defined by the class. If a circumflex is actually required as a
+member of the class, ensure it is not the first character, or escape it with a
backslash.
.P
For example, the character class [aeiou] matches any lower case vowel, while
@@ -1011,19 +1082,20 @@
string, and therefore it fails if the current pointer is at the end of the
string.
.P
-In UTF-8 mode, characters with values greater than 255 can be included in a
-class as a literal string of bytes, or by using the \ex{ escaping mechanism.
+In UTF-8 (UTF-16) mode, characters with values greater than 255 (0xffff) can be
+included in a class as a literal string of data units, or by using the \ex{
+escaping mechanism.
.P
When caseless matching is set, any letters in a class represent both their
upper case and lower case versions, so for example, a caseless [aeiou] matches
"A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a
-caseful version would. In UTF-8 mode, PCRE always understands the concept of
+caseful version would. In a UTF mode, PCRE always understands the concept of
case for characters whose values are less than 128, so caseless matching is
always possible. For characters with higher values, the concept of case is
supported if PCRE is compiled with Unicode property support, but not otherwise.
-If you want to use caseless matching in UTF8-mode for characters 128 and above,
-you must ensure that PCRE is compiled with Unicode property support as well as
-with UTF-8 support.
+If you want to use caseless matching in a UTF mode for characters 128 and
+above, you must ensure that PCRE is compiled with Unicode property support as
+well as with UTF support.
.P
Characters that might indicate line breaks are never treated in any special way
when matching character classes, whatever line-ending sequence is in use, and
@@ -1045,22 +1117,21 @@
"]" can also be used to end a range.
.P
Ranges operate in the collating sequence of character values. They can also be
-used for characters specified numerically, for example [\e000-\e037]. In UTF-8
-mode, ranges can include characters whose values are greater than 255, for
-example [\ex{100}-\ex{2ff}].
+used for characters specified numerically, for example [\e000-\e037]. Ranges
+can include any characters that are valid for the current mode.
.P
If a range that includes letters is used when caseless matching is set, it
matches the letters in either case. For example, [W-c] is equivalent to
-[][\e\e^_`wxyzabc], matched caselessly, and in non-UTF-8 mode, if character
+[][\e\e^_`wxyzabc], matched caselessly, and in a non-UTF mode, if character
tables for a French locale are in use, [\exc8-\excb] matches accented E
-characters in both cases. In UTF-8 mode, PCRE supports the concept of case for
+characters in both cases. In UTF modes, PCRE supports the concept of case for
characters with values greater than 128 only when it is compiled with Unicode
property support.
.P
The character escape sequences \ed, \eD, \eh, \eH, \ep, \eP, \es, \eS, \ev,
\eV, \ew, and \eW may appear in a character class, and add the characters that
they match to the class. For example, [\edABCDEF] matches any hexadecimal
-digit. In UTF-8 mode, the PCRE_UCP option affects the meanings of \ed, \es, \ew
+digit. In UTF modes, the PCRE_UCP option affects the meanings of \ed, \es, \ew
and their upper case partners, just as it does when they appear outside a
character class, as described in the section entitled
.\" HTML
@@ -1130,7 +1201,7 @@
syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not
supported, and an error is given if they are encountered.
.P
-By default, in UTF-8 mode, characters with values greater than 128 do not match
+By default, in UTF modes, characters with values greater than 128 do not match
any of the POSIX character classes. However, if the PCRE_UCP option is passed
to \fBpcre_compile()\fP, some of the classes are changed so that Unicode
character properties are used. This is achieved by replacing the POSIX classes
@@ -1218,17 +1289,17 @@
behaviour otherwise.
.P
\fBNote:\fP There are other PCRE-specific options that can be set by the
-application when the compile or match functions are called. In some cases the
-pattern can contain special leading sequences such as (*CRLF) to override what
-the application has set or what has been defaulted. Details are given in the
-section entitled
+application when the compiling or matching functions are called. In some cases
+the pattern can contain special leading sequences such as (*CRLF) to override
+what the application has set or what has been defaulted. Details are given in
+the section entitled
.\" HTML
.\"
"Newline sequences"
.\"
-above. There are also the (*UTF8) and (*UCP) leading sequences that can be used
-to set UTF-8 and Unicode property modes; they are equivalent to setting the
-PCRE_UTF8 and the PCRE_UCP options, respectively.
+above. There are also the (*UTF8), (*UTF16), and (*UCP) leading sequences that
+can be used to set UTF and Unicode property modes; they are equivalent to
+setting the PCRE_UTF8, PCRE_UTF16, and the PCRE_UCP options, respectively.
.
.
.\" HTML
@@ -1247,10 +1318,13 @@
.sp
2. It sets up the subpattern as a capturing subpattern. This means that, when
the whole pattern matches, that portion of the subject string that matched the
-subpattern is passed back to the caller via the \fIovector\fP argument of
-\fBpcre_exec()\fP. Opening parentheses are counted from left to right (starting
-from 1) to obtain numbers for the capturing subpatterns. For example, if the
-string "the red king" is matched against the pattern
+subpattern is passed back to the caller via the \fIovector\fP argument of the
+matching function. (This applies only to the traditional matching functions;
+the DFA matching functions do not support capturing.)
+.P
+Opening parentheses are counted from left to right (starting from 1) to obtain
+numbers for the capturing subpatterns. For example, if the string "the red
+king" is matched against the pattern
.sp
the ((red|white) (king|queen))
.sp
@@ -1313,9 +1387,9 @@
.sp
/(?|(abc)|(def))\e1/
.sp
-In contrast, a recursive or "subroutine" call to a numbered subpattern always
-refers to the first one in the pattern with the given number. The following
-pattern matches "abcabc" or "defabc":
+In contrast, a subroutine call to a numbered subpattern always refers to the
+first one in the pattern with the given number. The following pattern matches
+"abcabc" or "defabc":
.sp
/(?|(abc)|(def))(?1)/
.sp
@@ -1426,13 +1500,13 @@
a literal data character
the dot metacharacter
the \eC escape sequence
- the \eX escape sequence (in UTF-8 mode with Unicode properties)
+ the \eX escape sequence
the \eR escape sequence
an escape such as \ed or \epL that matches a single character
a character class
a back reference (see next section)
- a parenthesized subpattern (unless it is an assertion)
- a recursive or "subroutine" call to a subpattern
+ a parenthesized subpattern (including assertions)
+ a subroutine call to a subpattern (recursive or otherwise)
.sp
The general repetition quantifier specifies a minimum and maximum number of
permitted matches, by giving the two numbers in curly brackets (braces),
@@ -1457,11 +1531,11 @@
quantifier, is taken as a literal character. For example, {,6} is not a
quantifier, but a literal string of four characters.
.P
-In UTF-8 mode, quantifiers apply to UTF-8 characters rather than to individual
-bytes. Thus, for example, \ex{100}{2} matches two UTF-8 characters, each of
-which is represented by a two-byte sequence. Similarly, when Unicode property
-support is available, \eX{3} matches three Unicode extended sequences, each of
-which may be several bytes long (and they may be of different lengths).
+In UTF modes, quantifiers apply to characters rather than to individual data
+units. Thus, for example, \ex{100}{2} matches two characters, each of
+which is represented by a two-byte sequence in a UTF-8 string. Similarly,
+\eX{3} matches three Unicode extended sequences, each of which may be several
+data units long (and they may be of different lengths).
.P
The quantifier {0} is permitted, causing the expression to behave as if the
previous item and the quantifier were not present. This may be useful for
@@ -1771,7 +1845,7 @@
following a backslash are taken as part of a potential back reference number.
If the pattern continues with a digit character, some delimiter must be used to
terminate the back reference. If the PCRE_EXTENDED option is set, this can be
-whitespace. Otherwise, the \eg{ syntax or an empty comment (see
+white space. Otherwise, the \eg{ syntax or an empty comment (see
.\" HTML
.\"
"Comments"
@@ -1822,12 +1896,31 @@
that look behind it. An assertion subpattern is matched in the normal way,
except that it does not cause the current matching position to be changed.
.P
-Assertion subpatterns are not capturing subpatterns, and may not be repeated,
-because it makes no sense to assert the same thing several times. If any kind
-of assertion contains capturing subpatterns within it, these are counted for
-the purposes of numbering the capturing subpatterns in the whole pattern.
-However, substring capturing is carried out only for positive assertions,
-because it does not make sense for negative assertions.
+Assertion subpatterns are not capturing subpatterns. If such an assertion
+contains capturing subpatterns within it, these are counted for the purposes of
+numbering the capturing subpatterns in the whole pattern. However, substring
+capturing is carried out only for positive assertions, because it does not make
+sense for negative assertions.
+.P
+For compatibility with Perl, assertion subpatterns may be repeated; though
+it makes no sense to assert the same thing several times, the side effect of
+capturing parentheses may occasionally be useful. In practice, there only three
+cases:
+.sp
+(1) If the quantifier is {0}, the assertion is never obeyed during matching.
+However, it may contain internal capturing parenthesized groups that are called
+from elsewhere via the
+.\" HTML
+.\"
+subroutine mechanism.
+.\"
+.sp
+(2) If quantifier is {0,n} where n is greater than zero, it is treated as if it
+were {0,1}. At run time, the rest of the pattern match is tried with and
+without the assertion, the order depending on the greediness of the quantifier.
+.sp
+(3) If the minimum repetition is greater than zero, the quantifier is ignored.
+The assertion is obeyed just once when encountered during matching.
.
.
.SS "Lookahead assertions"
@@ -1905,10 +1998,11 @@
match. If there are insufficient characters before the current position, the
assertion fails.
.P
-PCRE does not allow the \eC escape (which matches a single byte in UTF-8 mode)
-to appear in lookbehind assertions, because it makes it impossible to calculate
-the length of the lookbehind. The \eX and \eR escapes, which can match
-different numbers of bytes, are also not permitted.
+In a UTF mode, PCRE does not allow the \eC escape (which matches a single data
+unit even in a UTF mode) to appear in lookbehind assertions, because it makes
+it impossible to calculate the length of the lookbehind. The \eX and \eR
+escapes, which can match different numbers of data units, are also not
+permitted.
.P
.\" HTML
.\"
@@ -2102,13 +2196,13 @@
name DEFINE, the condition is always false. In this case, there may be only one
alternative in the subpattern. It is always skipped if control reaches this
point in the pattern; the idea of DEFINE is that it can be used to define
-"subroutines" that can be referenced from elsewhere. (The use of
+subroutines that can be referenced from elsewhere. (The use of
.\" HTML
.\"
-"subroutines"
+subroutines
.\"
is described below.) For example, a pattern to match an IPv4 address such as
-"192.168.23.245" could be written like this (ignore whitespace and line
+"192.168.23.245" could be written like this (ignore white space and line
breaks):
.sp
(?(DEFINE) (? 2[0-4]\ed | 25[0-5] | 1\ed\ed | [1-9]?\ed) )
@@ -2155,7 +2249,7 @@
option is set, an unescaped # character also introduces a comment, which in
this case continues to immediately after the next newline character or
character sequence in the pattern. Which characters are interpreted as newlines
-is controlled by the options passed to \fBpcre_compile()\fP or by a special
+is controlled by the options passed to a compiling function or by a special
sequence at the start of the pattern, as described in the section entitled
.\" HTML
.\"
@@ -2200,11 +2294,11 @@
this kind of recursion was subsequently introduced into Perl at release 5.10.
.P
A special item that consists of (? followed by a number greater than zero and a
-closing parenthesis is a recursive call of the subpattern of the given number,
-provided that it occurs inside that subpattern. (If not, it is a
+closing parenthesis is a recursive subroutine call of the subpattern of the
+given number, provided that it occurs inside that subpattern. (If not, it is a
.\" HTML
.\"
-"subroutine"
+non-recursive subroutine
.\"
call, which is described in the next section.) The special item (?R) or (?0) is
a recursive call of the entire regular expression.
@@ -2239,7 +2333,7 @@
reference is not inside the parentheses that are referenced. They are always
.\" HTML
.\"
-"subroutine"
+non-recursive subroutine
.\"
calls, as described in the next section.
.P
@@ -2276,8 +2370,8 @@
.sp
the value for the inner capturing parentheses (numbered 2) is "ef", which is
the last value taken on at the top level. If a capturing subpattern is not
-matched at the top level, its final value is unset, even if it is (temporarily)
-set at a deeper level.
+matched at the top level, its final captured value is unset, even if it was
+(temporarily) set at a deeper level during the matching process.
.P
If there are more than 15 capturing parentheses in a pattern, PCRE has to
obtain extra memory to store data during a recursion, which it does by using
@@ -2297,15 +2391,16 @@
.
.
.\" HTML
-.SS "Recursion difference from Perl"
+.SS "Differences in recursion processing between PCRE and Perl"
.rs
.sp
-In PCRE (like Python, but unlike Perl), a recursive subpattern call is always
-treated as an atomic group. That is, once it has matched some of the subject
-string, it is never re-entered, even if it contains untried alternatives and
-there is a subsequent matching failure. This can be illustrated by the
-following pattern, which purports to match a palindromic string that contains
-an odd number of characters (for example, "a", "aba", "abcba", "abcdcba"):
+Recursion processing in PCRE differs from Perl in two important ways. In PCRE
+(like Python, but unlike Perl), a recursive subpattern call is always treated
+as an atomic group. That is, once it has matched some of the subject string, it
+is never re-entered, even if it contains untried alternatives and there is a
+subsequent matching failure. This can be illustrated by the following pattern,
+which purports to match a palindromic string that contains an odd number of
+characters (for example, "a", "aba", "abcba", "abcdcba"):
.sp
^(.|(.)(?1)\e2)$
.sp
@@ -2366,15 +2461,30 @@
PCRE finds the palindrome "aba" at the start, then fails at top level because
the end of the string does not follow. Once again, it cannot jump back into the
recursion to try other alternatives, so the entire match fails.
+.P
+The second way in which PCRE and Perl differ in their recursion processing is
+in the handling of captured values. In Perl, when a subpattern is called
+recursively or as a subpattern (see the next section), it has no access to any
+values that were captured outside the recursion, whereas in PCRE these values
+can be referenced. Consider this pattern:
+.sp
+ ^(.)(\e1|a(?2))
+.sp
+In PCRE, this pattern matches "bab". The first capturing parentheses match "b",
+then in the second group, when the back reference \e1 fails to match "b", the
+second alternative matches "a" and then recurses. In the recursion, \e1 does
+now match "b" and so the whole match succeeds. In Perl, the pattern fails to
+match because inside the recursive call \e1 cannot access the externally set
+value.
.
.
.\" HTML
.SH "SUBPATTERNS AS SUBROUTINES"
.rs
.sp
-If the syntax for a recursive subpattern reference (either by number or by
+If the syntax for a recursive subpattern call (either by number or by
name) is used outside the parentheses to which it refers, it operates like a
-subroutine in a programming language. The "called" subpattern may be defined
+subroutine in a programming language. The called subpattern may be defined
before or after the reference. A numbered reference can be absolute or
relative, as in these examples:
.sp
@@ -2394,15 +2504,15 @@
is used, it does match "sense and responsibility" as well as the other two
strings. Another example is given in the discussion of DEFINE above.
.P
-Like recursive subpatterns, a subroutine call is always treated as an atomic
-group. That is, once it has matched some of the subject string, it is never
-re-entered, even if it contains untried alternatives and there is a subsequent
-matching failure. Any capturing parentheses that are set during the subroutine
-call revert to their previous values afterwards.
-.P
-When a subpattern is used as a subroutine, processing options such as
-case-independence are fixed when the subpattern is defined. They cannot be
-changed for different calls. For example, consider this pattern:
+All subroutine calls, whether recursive or not, are always treated as atomic
+groups. That is, once a subroutine has matched some of the subject string, it
+is never re-entered, even if it contains untried alternatives and there is a
+subsequent matching failure. Any capturing parentheses that are set during the
+subroutine call revert to their previous values afterwards.
+.P
+Processing options such as case-independence are fixed when a subpattern is
+defined, so if it is used as a subroutine, such options cannot be changed for
+different calls. For example, consider this pattern:
.sp
(abc)(?i:(?-1))
.sp
@@ -2441,8 +2551,9 @@
.P
PCRE provides a similar feature, but of course it cannot obey arbitrary Perl
code. The feature is called "callout". The caller of PCRE provides an external
-function by putting its entry point in the global variable \fIpcre_callout\fP.
-By default, this variable contains NULL, which disables all calling out.
+function by putting its entry point in the global variable \fIpcre_callout\fP
+(8-bit library) or \fIpcre16_callout\fP (16-bit library). By default, this
+variable contains NULL, which disables all calling out.
.P
Within a regular expression, (?C) indicates the points at which the external
function is to be called. If you want to identify different callout points, you
@@ -2451,16 +2562,16 @@
.sp
(?C1)abc(?C2)def
.sp
-If the PCRE_AUTO_CALLOUT flag is passed to \fBpcre_compile()\fP, callouts are
+If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, callouts are
automatically installed before each item in the pattern. They are all numbered
255.
.P
-During matching, when PCRE reaches a callout point (and \fIpcre_callout\fP is
-set), the external function is called. It is provided with the number of the
-callout, the position in the pattern, and, optionally, one item of data
-originally supplied by the caller of \fBpcre_exec()\fP. The callout function
-may cause matching to proceed, to backtrack, or to fail altogether. A complete
-description of the interface to the callout function is given in the
+During matching, when PCRE reaches a callout point, the external function is
+called. It is provided with the number of the callout, the position in the
+pattern, and, optionally, one item of data originally supplied by the caller of
+the matching function. The callout function may cause matching to proceed, to
+backtrack, or to fail altogether. A complete description of the interface to
+the callout function is given in the
.\" HREF
\fBpcrecallout\fP
.\"
@@ -2478,24 +2589,35 @@
remarks apply to the PCRE features described in this section.
.P
Since these verbs are specifically related to backtracking, most of them can be
-used only when the pattern is to be matched using \fBpcre_exec()\fP, which uses
-a backtracking algorithm. With the exception of (*FAIL), which behaves like a
-failing negative assertion, they cause an error if encountered by
-\fBpcre_dfa_exec()\fP.
-.P
-If any of these verbs are used in an assertion or subroutine subpattern
-(including recursive subpatterns), their effect is confined to that subpattern;
-it does not extend to the surrounding pattern. Note that such subpatterns are
-processed as anchored at the point where they are tested.
+used only when the pattern is to be matched using one of the traditional
+matching functions, which use a backtracking algorithm. With the exception of
+(*FAIL), which behaves like a failing negative assertion, they cause an error
+if encountered by a DFA matching function.
+.P
+If any of these verbs are used in an assertion or in a subpattern that is
+called as a subroutine (whether or not recursively), their effect is confined
+to that subpattern; it does not extend to the surrounding pattern, with one
+exception: the name from a *(MARK), (*PRUNE), or (*THEN) that is encountered in
+a successful positive assertion \fIis\fP passed back when a match succeeds
+(compare capturing parentheses in assertions). Note that such subpatterns are
+processed as anchored at the point where they are tested. Note also that Perl's
+treatment of subroutines and assertions is different in some cases.
.P
The new verbs make use of what was previously invalid syntax: an opening
parenthesis followed by an asterisk. They are generally of the form
(*VERB) or (*VERB:NAME). Some may take either form, with differing behaviour,
-depending on whether or not an argument is present. An name is a sequence of
-letters, digits, and underscores. If the name is empty, that is, if the closing
-parenthesis immediately follows the colon, the effect is as if the colon were
-not there. Any number of these verbs may occur in a pattern.
-.P
+depending on whether or not an argument is present. A name is any sequence of
+characters that does not include a closing parenthesis. The maximum length of
+name is 255 in the 8-bit library and 65535 in the 16-bit library. If the name
+is empty, that is, if the closing parenthesis immediately follows the colon,
+the effect is as if the colon were not there. Any number of these verbs may
+occur in a pattern.
+.
+.
+.\" HTML
+.SS "Optimizations that affect backtracking verbs"
+.rs
+.sp
PCRE contains some optimizations that are used to speed up matching by running
some checks at the start of each match attempt. For example, it may know the
minimum length of matching subject, or that a particular character must be
@@ -2503,7 +2625,20 @@
included backtracking verbs will not, of course, be processed. You can suppress
the start-of-match optimizations by setting the PCRE_NO_START_OPTIMIZE option
when calling \fBpcre_compile()\fP or \fBpcre_exec()\fP, or by starting the
-pattern with (*NO_START_OPT).
+pattern with (*NO_START_OPT). There is more discussion of this option in the
+section entitled
+.\" HTML
+.\"
+"Option bits for \fBpcre_exec()\fP"
+.\"
+in the
+.\" HREF
+\fBpcreapi\fP
+.\"
+documentation.
+.P
+Experiments with Perl suggest that it too has similar optimizations, sometimes
+leading to anomalous results.
.
.
.SS "Verbs that act immediately"
@@ -2515,9 +2650,10 @@
(*ACCEPT)
.sp
This verb causes the match to end successfully, skipping the remainder of the
-pattern. When inside a recursion, only the innermost pattern is ended
-immediately. If (*ACCEPT) is inside capturing parentheses, the data so far is
-captured. (This feature was added to PCRE at release 8.00.) For example:
+pattern. However, when it is inside a subpattern that is called as a
+subroutine, only that subpattern is ended successfully. Matching then continues
+at the outer level. If (*ACCEPT) is inside capturing parentheses, the data so
+far is captured. For example:
.sp
A((?:A|B(*ACCEPT)|C)D)
.sp
@@ -2526,7 +2662,7 @@
.sp
(*FAIL) or (*F)
.sp
-This verb causes the match to fail, forcing backtracking to occur. It is
+This verb causes a matching failure, forcing backtracking to occur. It is
equivalent to (?!) but easier to read. The Perl documentation notes that it is
probably useful only when combined with (?{}) or (??{}). Those are, of course,
Perl features that are not present in PCRE. The nearest equivalent is the
@@ -2550,22 +2686,21 @@
A name is always required with this verb. There may be as many instances of
(*MARK) as you like in a pattern, and their names do not have to be unique.
.P
-When a match succeeds, the name of the last-encountered (*MARK) is passed back
-to the caller via the \fIpcre_extra\fP data structure, as described in the
+When a match succeeds, the name of the last-encountered (*MARK) on the matching
+path is passed back to the caller as described in the section entitled
.\" HTML
.\"
-section on \fIpcre_extra\fP
+"Extra data for \fBpcre_exec()\fP"
.\"
in the
.\" HREF
\fBpcreapi\fP
.\"
-documentation. No data is returned for a partial match. Here is an example of
-\fBpcretest\fP output, where the /K modifier requests the retrieval and
-outputting of (*MARK) data:
+documentation. Here is an example of \fBpcretest\fP output, where the /K
+modifier requests the retrieval and outputting of (*MARK) data:
.sp
- /X(*MARK:A)Y|X(*MARK:B)Z/K
- XY
+ re> /X(*MARK:A)Y|X(*MARK:B)Z/K
+ data> XY
0: XY
MK: A
XZ
@@ -2577,31 +2712,29 @@
of obtaining this information than putting each alternative in its own
capturing parentheses.
.P
-A name may also be returned after a failed match if the final path through the
-pattern involves (*MARK). However, unless (*MARK) used in conjunction with
-(*COMMIT), this is unlikely to happen for an unanchored pattern because, as the
-starting point for matching is advanced, the final check is often with an empty
-string, causing a failure before (*MARK) is reached. For example:
-.sp
- /X(*MARK:A)Y|X(*MARK:B)Z/K
- XP
- No match
-.sp
-There are three potential starting points for this match (starting with X,
-starting with P, and with an empty string). If the pattern is anchored, the
-result is different:
+If (*MARK) is encountered in a positive assertion, its name is recorded and
+passed back if it is the last-encountered. This does not happen for negative
+assertions.
+.P
+After a partial match or a failed match, the name of the last encountered
+(*MARK) in the entire match process is returned. For example:
.sp
- /^X(*MARK:A)Y|^X(*MARK:B)Z/K
- XP
+ re> /X(*MARK:A)Y|X(*MARK:B)Z/K
+ data> XP
No match, mark = B
.sp
-PCRE's start-of-match optimizations can also interfere with this. For example,
-if, as a result of a call to \fBpcre_study()\fP, it knows the minimum
-subject length for a match, a shorter subject will not be scanned at all.
-.P
-Note that similar anomalies (though different in detail) exist in Perl, no
-doubt for the same reasons. The use of (*MARK) data after a failed match of an
-unanchored pattern is not recommended, unless (*COMMIT) is involved.
+Note that in this unanchored example the mark is retained from the match
+attempt that started at the letter "X" in the subject. Subsequent match
+attempts starting at "P" and then with an empty string do not get as far as the
+(*MARK) item, but nevertheless do not reset it.
+.P
+If you are interested in (*MARK) values after failed matches, you should
+probably set the PCRE_NO_START_OPTIMIZE option
+.\" HTML
+.\"
+(see above)
+.\"
+to ensure that the match is always attempted.
.
.
.SS "Verbs that act after backtracking"
@@ -2638,8 +2771,8 @@
unless PCRE's start-of-match optimizations are turned off, as shown in this
\fBpcretest\fP example:
.sp
- /(*COMMIT)abc/
- xyzabc
+ re> /(*COMMIT)abc/
+ data> xyzabc
0: abc
xyzabc\eY
No match
@@ -2660,10 +2793,8 @@
the right, backtracking cannot cross (*PRUNE). In simple cases, the use of
(*PRUNE) is just an alternative to an atomic group or possessive quantifier,
but there are some uses of (*PRUNE) that cannot be expressed in any other way.
-The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE) when the
-match fails completely; the name is passed back if this is the final attempt.
-(*PRUNE:NAME) does not pass back a name if the match succeeds. In an anchored
-pattern (*PRUNE) has the same effect as (*COMMIT).
+The behaviour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an
+anchored pattern (*PRUNE) has the same effect as (*COMMIT).
.sp
(*SKIP)
.sp
@@ -2689,41 +2820,75 @@
searched for the most recent (*MARK) that has the same name. If one is found,
the "bumpalong" advance is to the subject position that corresponds to that
(*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with a
-matching name is found, normal "bumpalong" of one character happens (the
-(*SKIP) is ignored).
+matching name is found, the (*SKIP) is ignored.
.sp
(*THEN) or (*THEN:NAME)
.sp
-This verb causes a skip to the next alternation in the innermost enclosing
-group if the rest of the pattern does not match. That is, it cancels pending
-backtracking, but only within the current alternation. Its name comes from the
-observation that it can be used for a pattern-based if-then-else block:
+This verb causes a skip to the next innermost alternative if the rest of the
+pattern does not match. That is, it cancels pending backtracking, but only
+within the current alternative. Its name comes from the observation that it can
+be used for a pattern-based if-then-else block:
.sp
( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ...
.sp
If the COND1 pattern matches, FOO is tried (and possibly further items after
-the end of the group if FOO succeeds); on failure the matcher skips to the
+the end of the group if FOO succeeds); on failure, the matcher skips to the
second alternative and tries COND2, without backtracking into COND1. The
-behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN) if the
-overall match fails. If (*THEN) is not directly inside an alternation, it acts
-like (*PRUNE).
-.
-.P
-The above verbs provide four different "strengths" of control when subsequent
-matching fails. (*THEN) is the weakest, carrying on the match at the next
-alternation. (*PRUNE) comes next, failing the match at the current starting
-position, but allowing an advance to the next character (for an unanchored
-pattern). (*SKIP) is similar, except that the advance may be more than one
-character. (*COMMIT) is the strongest, causing the entire match to fail.
+behaviour of (*THEN:NAME) is exactly the same as (*MARK:NAME)(*THEN).
+If (*THEN) is not inside an alternation, it acts like (*PRUNE).
.P
-If more than one is present in a pattern, the "stongest" one wins. For example,
-consider this pattern, where A, B, etc. are complex pattern fragments:
+Note that a subpattern that does not contain a | character is just a part of
+the enclosing alternative; it is not a nested alternation with only one
+alternative. The effect of (*THEN) extends beyond such a subpattern to the
+enclosing alternative. Consider this pattern, where A, B, etc. are complex
+pattern fragments that do not contain any | characters at this level:
+.sp
+ A (B(*THEN)C) | D
+.sp
+If A and B are matched, but there is a failure in C, matching does not
+backtrack into A; instead it moves to the next alternative, that is, D.
+However, if the subpattern containing (*THEN) is given an alternative, it
+behaves differently:
+.sp
+ A (B(*THEN)C | (*FAIL)) | D
+.sp
+The effect of (*THEN) is now confined to the inner subpattern. After a failure
+in C, matching moves to (*FAIL), which causes the whole subpattern to fail
+because there are no more alternatives to try. In this case, matching does now
+backtrack into A.
+.P
+Note also that a conditional subpattern is not considered as having two
+alternatives, because only one is ever used. In other words, the | character in
+a conditional subpattern has a different meaning. Ignoring white space,
+consider:
+.sp
+ ^.*? (?(?=a) a | b(*THEN)c )
+.sp
+If the subject is "ba", this pattern does not match. Because .*? is ungreedy,
+it initially matches zero characters. The condition (?=a) then fails, the
+character "b" is matched, but "c" is not. At this point, matching does not
+backtrack to .*? as might perhaps be expected from the presence of the |
+character. The conditional subpattern is part of the single alternative that
+comprises the whole pattern, and so the match fails. (If there was a backtrack
+into .*?, allowing it to match "b", the match would succeed.)
+.P
+The verbs just described provide four different "strengths" of control when
+subsequent matching fails. (*THEN) is the weakest, carrying on the match at the
+next alternative. (*PRUNE) comes next, failing the match at the current
+starting position, but allowing an advance to the next character (for an
+unanchored pattern). (*SKIP) is similar, except that the advance may be more
+than one character. (*COMMIT) is the strongest, causing the entire match to
+fail.
+.P
+If more than one such verb is present in a pattern, the "strongest" one wins.
+For example, consider this pattern, where A, B, etc. are complex pattern
+fragments:
.sp
(A(*COMMIT)B(*THEN)C|D)
.sp
Once A has matched, PCRE is committed to this match, at the current starting
position. If subsequently B matches, but C does not, the normal (*THEN) action
-of trying the next alternation (that is, D) does not happen because (*COMMIT)
+of trying the next alternative (that is, D) does not happen because (*COMMIT)
overrides.
.
.
@@ -2731,7 +2896,7 @@
.rs
.sp
\fBpcreapi\fP(3), \fBpcrecallout\fP(3), \fBpcrematching\fP(3),
-\fBpcresyntax\fP(3), \fBpcre\fP(3).
+\fBpcresyntax\fP(3), \fBpcre\fP(3), \fBpcre16(3)\fP.
.
.
.SH AUTHOR
@@ -2748,6 +2913,6 @@
.rs
.sp
.nf
-Last updated: 21 November 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 17 June 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcreperform.3 pcre3-8.31/doc/pcreperform.3
--- pcre3-8.12/doc/pcreperform.3 2010-06-03 19:15:23.000000000 +0000
+++ pcre3-8.31/doc/pcreperform.3 2012-03-31 18:03:11.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCREPERFORM 3
+.TH PCREPERFORM 3 "09 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PCRE PERFORMANCE"
@@ -11,9 +11,9 @@
.SH "COMPILED PATTERN MEMORY USAGE"
.rs
.sp
-Patterns are compiled by PCRE into a reasonably efficient byte code, so that
-most simple patterns do not use much memory. However, there is one case where
-the memory usage of a compiled pattern can be unexpectedly large. If a
+Patterns are compiled by PCRE into a reasonably efficient interpretive code, so
+that most simple patterns do not use much memory. However, there is one case
+where the memory usage of a compiled pattern can be unexpectedly large. If a
parenthesized subpattern has a quantifier with a minimum greater than 1 and/or
a limited maximum, the whole subpattern is repeated in the compiled code. For
example, the pattern
@@ -34,12 +34,12 @@
.sp
((ab){1,1000}c){1,3}
.sp
-uses 51K bytes when compiled. When PCRE is compiled with its default internal
-pointer size of two bytes, the size limit on a compiled pattern is 64K, and
-this is reached with the above pattern if the outer repetition is increased
-from 3 to 4. PCRE can be compiled to use larger internal pointers and thus
-handle larger compiled patterns, but it is better to try to rewrite your
-pattern to use less memory if you can.
+uses 51K bytes when compiled using the 8-bit library. When PCRE is compiled
+with its default internal pointer size of two bytes, the size limit on a
+compiled pattern is 64K data units, and this is reached with the above pattern
+if the outer repetition is increased from 3 to 4. PCRE can be compiled to use
+larger internal pointers and thus handle larger compiled patterns, but it is
+better to try to rewrite your pattern to use less memory if you can.
.P
One way of reducing the memory usage for such patterns is to make use of PCRE's
.\" HTML
@@ -68,11 +68,11 @@
.SH "STACK USAGE AT RUN TIME"
.rs
.sp
-When \fBpcre_exec()\fP is used for matching, certain kinds of pattern can cause
-it to use large amounts of the process stack. In some environments the default
-process stack is quite small, and if it runs out the result is often SIGSEGV.
-This issue is probably the most frequently raised problem with PCRE. Rewriting
-your pattern can often help. The
+When \fBpcre_exec()\fP or \fBpcre16_exec()\fP is used for matching, certain
+kinds of pattern can cause it to use large amounts of the process stack. In
+some environments the default process stack is quite small, and if it runs out
+the result is often SIGSEGV. This issue is probably the most frequently raised
+problem with PCRE. Rewriting your pattern can often help. The
.\" HREF
\fBpcrestack\fP
.\"
@@ -101,8 +101,9 @@
backwards compatibility, and partly for performance reasons. However, you can
set PCRE_UCP if you want Unicode character properties to be used. This can
double the matching time for items such as \ed, when matched with
-\fBpcre_exec()\fP; the performance loss is less with \fBpcre_dfa_exec()\fP, and
-in both cases there is not much difference for \eb.
+a traditional matching function; the performance loss is less with
+a DFA matching function, and in both cases there is not much difference for
+\eb.
.P
When a pattern begins with .* not in parentheses, or in parentheses that are
not the subject of a backreference, and the PCRE_DOTALL option is set, the
@@ -172,6 +173,6 @@
.rs
.sp
.nf
-Last updated: 16 May 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 09 January 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcreposix.3 pcre3-8.31/doc/pcreposix.3
--- pcre3-8.12/doc/pcreposix.3 2010-05-16 18:38:26.000000000 +0000
+++ pcre3-8.31/doc/pcreposix.3 2012-03-31 18:03:27.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCREPOSIX 3
+.TH PCREPOSIX 3 "09 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions.
.SH "SYNOPSIS OF POSIX API"
@@ -24,13 +24,14 @@
.SH DESCRIPTION
.rs
.sp
-This set of functions provides a POSIX-style API to the PCRE regular expression
-package. See the
+This set of functions provides a POSIX-style API for the PCRE regular
+expression 8-bit library. See the
.\" HREF
\fBpcreapi\fP
.\"
documentation for a description of PCRE's native API, which contains much
-additional functionality.
+additional functionality. There is no POSIX-style wrapper for PCRE's 16-bit
+library.
.P
The functions described here are just wrapper functions that ultimately call
the PCRE native API. Their prototypes are defined in the \fBpcreposix.h\fP
@@ -264,6 +265,6 @@
.rs
.sp
.nf
-Last updated: 16 May 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 09 January 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcreprecompile.3 pcre3-8.31/doc/pcreprecompile.3
--- pcre3-8.12/doc/pcreprecompile.3 2011-01-11 16:34:02.000000000 +0000
+++ pcre3-8.31/doc/pcreprecompile.3 2012-03-31 18:03:43.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCREPRECOMPILE 3
+.TH PCREPRECOMPILE 3 "10 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "SAVING AND RE-USING PRECOMPILED PCRE PATTERNS"
@@ -12,25 +12,31 @@
\fBpcre_maketables()\fP
.\"
documentation), this is relatively straightforward. If you are using private
-tables, it is a little bit more complicated.
+tables, it is a little bit more complicated. However, if you are using the
+just-in-time optimization feature, it is not possible to save and reload the
+JIT data.
.P
If you save compiled patterns to a file, you can copy them to a different host
-and run them there. This works even if the new host has the opposite endianness
-to the one on which the patterns were compiled. There may be a small
-performance penalty, but it should be insignificant. However, compiling regular
-expressions with one version of PCRE for use with a different version is not
-guaranteed to work and may cause crashes.
+and run them there. If the two hosts have different endianness (byte order),
+you should run the \fBpcre[16]_pattern_to_host_byte_order()\fP function on the
+new host before trying to match the pattern. The matching functions return
+PCRE_ERROR_BADENDIANNESS if they detect a pattern with the wrong endianness.
+.P
+Compiling regular expressions with one version of PCRE for use with a different
+version is not guaranteed to work and may cause crashes, and saving and
+restoring a compiled pattern loses any JIT optimization data.
.
.
.SH "SAVING A COMPILED PATTERN"
.rs
.sp
-The value returned by \fBpcre_compile()\fP points to a single block of memory
-that holds the compiled pattern and associated data. You can find the length of
-this block in bytes by calling \fBpcre_fullinfo()\fP with an argument of
-PCRE_INFO_SIZE. You can then save the data in any appropriate manner. Here is
-sample code that compiles a pattern and writes it to a file. It assumes that
-the variable \fIfd\fP refers to a file that is open for output:
+The value returned by \fBpcre[16]_compile()\fP points to a single block of
+memory that holds the compiled pattern and associated data. You can find the
+length of this block in bytes by calling \fBpcre[16]_fullinfo()\fP with an
+argument of PCRE_INFO_SIZE. You can then save the data in any appropriate
+manner. Here is sample code for the 8-bit library that compiles a pattern and
+writes it to a file. It assumes that the variable \fIfd\fP refers to a file
+that is open for output:
.sp
int erroroffset, rc, size;
char *error;
@@ -58,10 +64,12 @@
some daemon process that passes them via sockets to the processes that want
them.
.P
-If the pattern has been studied, it is also possible to save the study data in
-a similar way to the compiled pattern itself. When studying generates
-additional information, \fBpcre_study()\fP returns a pointer to a
-\fBpcre_extra\fP data block. Its format is defined in the
+If the pattern has been studied, it is also possible to save the normal study
+data in a similar way to the compiled pattern itself. However, if the
+PCRE_STUDY_JIT_COMPILE was used, the just-in-time data that is created cannot
+be saved because it is too dependent on the current environment. When studying
+generates additional information, \fBpcre[16]_study()\fP returns a pointer to a
+\fBpcre[16]_extra\fP data block. Its format is defined in the
.\" HTML
.\"
section on matching a pattern
@@ -71,26 +79,27 @@
\fBpcreapi\fP
.\"
documentation. The \fIstudy_data\fP field points to the binary study data, and
-this is what you must save (not the \fBpcre_extra\fP block itself). The length
-of the study data can be obtained by calling \fBpcre_fullinfo()\fP with an
-argument of PCRE_INFO_STUDYSIZE. Remember to check that \fBpcre_study()\fP did
-return a non-NULL value before trying to save the study data.
+this is what you must save (not the \fBpcre[16]_extra\fP block itself). The
+length of the study data can be obtained by calling \fBpcre[16]_fullinfo()\fP
+with an argument of PCRE_INFO_STUDYSIZE. Remember to check that
+\fBpcre[16]_study()\fP did return a non-NULL value before trying to save the
+study data.
.
.
.SH "RE-USING A PRECOMPILED PATTERN"
.rs
.sp
Re-using a precompiled pattern is straightforward. Having reloaded it into main
-memory, you pass its pointer to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP in
-the usual way. This should work even on another host, and even if that host has
-the opposite endianness to the one where the pattern was compiled.
+memory, called \fBpcre[16]_pattern_to_host_byte_order()\fP if necessary,
+you pass its pointer to \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP in
+the usual way.
.P
However, if you passed a pointer to custom character tables when the pattern
-was compiled (the \fItableptr\fP argument of \fBpcre_compile()\fP), you must
-now pass a similar pointer to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP,
-because the value saved with the compiled pattern will obviously be nonsense. A
-field in a \fBpcre_extra()\fP block is used to pass this data, as described in
-the
+was compiled (the \fItableptr\fP argument of \fBpcre[16]_compile()\fP), you
+must now pass a similar pointer to \fBpcre[16]_exec()\fP or
+\fBpcre[16]_dfa_exec()\fP, because the value saved with the compiled pattern
+will obviously be nonsense. A field in a \fBpcre[16]_extra()\fP block is used
+to pass this data, as described in the
.\" HTML
.\"
section on matching a pattern
@@ -102,16 +111,17 @@
documentation.
.P
If you did not provide custom character tables when the pattern was compiled,
-the pointer in the compiled pattern is NULL, which causes \fBpcre_exec()\fP to
-use PCRE's internal tables. Thus, you do not need to take any special action at
-run time in this case.
+the pointer in the compiled pattern is NULL, which causes the matching
+functions to use PCRE's internal tables. Thus, you do not need to take any
+special action at run time in this case.
.P
If you saved study data with the compiled pattern, you need to create your own
-\fBpcre_extra\fP data block and set the \fIstudy_data\fP field to point to the
+\fBpcre[16]_extra\fP data block and set the \fIstudy_data\fP field to point to the
reloaded study data. You must also set the PCRE_EXTRA_STUDY_DATA bit in the
\fIflags\fP field to indicate that study data is present. Then pass the
-\fBpcre_extra\fP block to \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP in the
-usual way.
+\fBpcre[16]_extra\fP block to the matching function in the usual way. If the
+pattern was studied for just-in-time optimization, that data cannot be saved,
+and so is lost by a save/restore cycle.
.
.
.SH "COMPATIBILITY WITH DIFFERENT PCRE RELEASES"
@@ -136,6 +146,6 @@
.rs
.sp
.nf
-Last updated: 17 November 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 10 January 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcresample.3 pcre3-8.31/doc/pcresample.3
--- pcre3-8.12/doc/pcresample.3 2010-11-17 17:49:27.000000000 +0000
+++ pcre3-8.31/doc/pcresample.3 2012-03-31 18:04:01.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRESAMPLE 3
+.TH PCRESAMPLE 3 "10 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PCRE SAMPLE PROGRAM"
@@ -13,11 +13,12 @@
documentation. If you do not have a copy of the PCRE distribution, you can save
this listing to re-create \fIpcredemo.c\fP.
.P
-The program compiles the regular expression that is its first argument, and
-matches it against the subject string in its second argument. No PCRE options
-are set, and default character tables are used. If matching succeeds, the
-program outputs the portion of the subject that matched, together with the
-contents of any captured substrings.
+The demonstration program, which uses the original PCRE 8-bit library, compiles
+the regular expression that is its first argument, and matches it against the
+subject string in its second argument. No PCRE options are set, and default
+character tables are used. If matching succeeds, the program outputs the
+portion of the subject that matched, together with the contents of any captured
+substrings.
.P
If the -g option is given on the command line, the program then goes on to
check for further matches of the same regular expression in the same subject
@@ -55,8 +56,8 @@
.\" HREF
\fBpcretest\fP,
.\"
-which supports many more facilities for testing regular expressions and the
-PCRE library. The
+which supports many more facilities for testing regular expressions and both
+PCRE libraries. The
.\" HREF
\fBpcredemo\fP
.\"
@@ -93,6 +94,6 @@
.rs
.sp
.nf
-Last updated: 17 November 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 10 January 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcrestack.3 pcre3-8.31/doc/pcrestack.3
--- pcre3-8.12/doc/pcrestack.3 2010-01-06 10:20:46.000000000 +0000
+++ pcre3-8.31/doc/pcrestack.3 2012-03-31 18:04:16.000000000 +0000
@@ -1,14 +1,17 @@
-.TH PCRESTACK 3
+.TH PCRESTACK 3 "21 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PCRE DISCUSSION OF STACK USAGE"
.rs
.sp
-When you call \fBpcre_exec()\fP, it makes use of an internal function called
-\fBmatch()\fP. This calls itself recursively at branch points in the pattern,
-in order to remember the state of the match so that it can back up and try a
-different alternative if the first one fails. As matching proceeds deeper and
-deeper into the tree of possibilities, the recursion depth increases.
+When you call \fBpcre[16]_exec()\fP, it makes use of an internal function
+called \fBmatch()\fP. This calls itself recursively at branch points in the
+pattern, in order to remember the state of the match so that it can back up and
+try a different alternative if the first one fails. As matching proceeds deeper
+and deeper into the tree of possibilities, the recursion depth increases. The
+\fBmatch()\fP function is also called in other circumstances, for example,
+whenever a parenthesized sub-pattern is entered, and in certain cases of
+repetition.
.P
Not all calls of \fBmatch()\fP increase the recursion depth; for an item such
as a* it may be called several times at the same level, after matching
@@ -16,21 +19,32 @@
the recursive call would immediately be passed back as the result of the
current call (a "tail recursion"), the function is just restarted instead.
.P
-The \fBpcre_dfa_exec()\fP function operates in an entirely different way, and
-uses recursion only when there is a regular expression recursion or subroutine
-call in the pattern. This includes the processing of assertion and "once-only"
-subpatterns, which are handled like subroutine calls. Normally, these are never
-very deep, and the limit on the complexity of \fBpcre_dfa_exec()\fP is
-controlled by the amount of workspace it is given. However, it is possible to
-write patterns with runaway infinite recursions; such patterns will cause
-\fBpcre_dfa_exec()\fP to run out of stack. At present, there is no protection
-against this.
+The above comments apply when \fBpcre[16]_exec()\fP is run in its normal
+interpretive manner. If the pattern was studied with the
+PCRE_STUDY_JIT_COMPILE option, and just-in-time compiling was successful, and
+the options passed to \fBpcre[16]_exec()\fP were not incompatible, the matching
+process uses the JIT-compiled code instead of the \fBmatch()\fP function. In
+this case, the memory requirements are handled entirely differently. See the
+.\" HREF
+\fBpcrejit\fP
+.\"
+documentation for details.
+.P
+The \fBpcre[16]_dfa_exec()\fP function operates in an entirely different way,
+and uses recursion only when there is a regular expression recursion or
+subroutine call in the pattern. This includes the processing of assertion and
+"once-only" subpatterns, which are handled like subroutine calls. Normally,
+these are never very deep, and the limit on the complexity of
+\fBpcre[16]_dfa_exec()\fP is controlled by the amount of workspace it is given.
+However, it is possible to write patterns with runaway infinite recursions;
+such patterns will cause \fBpcre[16]_dfa_exec()\fP to run out of stack. At
+present, there is no protection against this.
.P
-The comments that follow do NOT apply to \fBpcre_dfa_exec()\fP; they are
-relevant only for \fBpcre_exec()\fP.
+The comments that follow do NOT apply to \fBpcre[16]_dfa_exec()\fP; they are
+relevant only for \fBpcre[16]_exec()\fP without the JIT optimization.
.
.
-.SS "Reducing \fBpcre_exec()\fP's stack usage"
+.SS "Reducing \fBpcre[16]_exec()\fP's stack usage"
.rs
.sp
Each time that \fBmatch()\fP is actually called recursively, it uses memory
@@ -65,41 +79,42 @@
than one character whenever possible.
.
.
-.SS "Compiling PCRE to use heap instead of stack for \fBpcre_exec()\fP"
+.SS "Compiling PCRE to use heap instead of stack for \fBpcre[16]_exec()\fP"
.rs
.sp
In environments where stack memory is constrained, you might want to compile
PCRE to use heap memory instead of stack for remembering back-up points when
-\fBpcre_exec()\fP is running. This makes it run a lot more slowly, however.
+\fBpcre[16]_exec()\fP is running. This makes it run a lot more slowly, however.
Details of how to do this are given in the
.\" HREF
\fBpcrebuild\fP
.\"
documentation. When built in this way, instead of using the stack, PCRE obtains
and frees memory by calling the functions that are pointed to by the
-\fBpcre_stack_malloc\fP and \fBpcre_stack_free\fP variables. By default, these
-point to \fBmalloc()\fP and \fBfree()\fP, but you can replace the pointers to
-cause PCRE to use your own functions. Since the block sizes are always the
-same, and are always freed in reverse order, it may be possible to implement
-customized memory handlers that are more efficient than the standard functions.
+\fBpcre[16]_stack_malloc\fP and \fBpcre[16]_stack_free\fP variables. By
+default, these point to \fBmalloc()\fP and \fBfree()\fP, but you can replace
+the pointers to cause PCRE to use your own functions. Since the block sizes are
+always the same, and are always freed in reverse order, it may be possible to
+implement customized memory handlers that are more efficient than the standard
+functions.
.
.
-.SS "Limiting \fBpcre_exec()\fP's stack usage"
+.SS "Limiting \fBpcre[16]_exec()\fP's stack usage"
.rs
.sp
You can set limits on the number of times that \fBmatch()\fP is called, both in
-total and recursively. If a limit is exceeded, \fBpcre_exec()\fP returns an
+total and recursively. If a limit is exceeded, \fBpcre[16]_exec()\fP returns an
error code. Setting suitable limits should prevent it from running out of
stack. The default values of the limits are very large, and unlikely ever to
operate. They can be changed when PCRE is built, and they can also be set when
-\fBpcre_exec()\fP is called. For details of these interfaces, see the
+\fBpcre[16]_exec()\fP is called. For details of these interfaces, see the
.\" HREF
\fBpcrebuild\fP
.\"
documentation and the
.\" HTML
.\"
-section on extra data for \fBpcre_exec()\fP
+section on extra data for \fBpcre[16]_exec()\fP
.\"
in the
.\" HREF
@@ -108,18 +123,43 @@
documentation.
.P
As a very rough rule of thumb, you should reckon on about 500 bytes per
-recursion. Thus, if you want to limit your stack usage to 8Mb, you
-should set the limit at 16000 recursions. A 64Mb stack, on the other hand, can
-support around 128000 recursions.
+recursion. Thus, if you want to limit your stack usage to 8Mb, you should set
+the limit at 16000 recursions. A 64Mb stack, on the other hand, can support
+around 128000 recursions.
.P
In Unix-like environments, the \fBpcretest\fP test program has a command line
option (\fB-S\fP) that can be used to increase the size of its stack. As long
as the stack is large enough, another option (\fB-M\fP) can be used to find the
smallest limits that allow a particular pattern to match a given subject
-string. This is done by calling \fBpcre_exec()\fP repeatedly with different
+string. This is done by calling \fBpcre[16]_exec()\fP repeatedly with different
limits.
.
.
+.SS "Obtaining an estimate of stack usage"
+.rs
+.sp
+The actual amount of stack used per recursion can vary quite a lot, depending
+on the compiler that was used to build PCRE and the optimization or debugging
+options that were set for it. The rule of thumb value of 500 bytes mentioned
+above may be larger or smaller than what is actually needed. A better
+approximation can be obtained by running this command:
+.sp
+ pcretest -m -C
+.sp
+The \fB-C\fP option causes \fBpcretest\fP to output information about the
+options with which PCRE was compiled. When \fB-m\fP is also given (before
+\fB-C\fP), information about stack use is given in a line like this:
+.sp
+ Match recursion uses stack: approximate frame size = 640 bytes
+.sp
+The value is approximate because some recursions need a bit more (up to perhaps
+16 more bytes).
+.P
+If the above command is given when PCRE is compiled to use the heap instead of
+the stack for recursion, the value that is output is the size of each block
+that is obtained from the heap.
+.
+.
.SS "Changing stack size in Unix-like systems"
.rs
.sp
@@ -141,7 +181,7 @@
.sp
This reads the current limits (soft and hard) using \fBgetrlimit()\fP, then
attempts to increase the soft limit to 100Mb using \fBsetrlimit()\fP. You must
-do this before calling \fBpcre_exec()\fP.
+do this before calling \fBpcre[16]_exec()\fP.
.
.
.SS "Changing stack size in Mac OS X"
@@ -170,6 +210,6 @@
.rs
.sp
.nf
-Last updated: 03 January 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 21 January 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcresyntax.3 pcre3-8.31/doc/pcresyntax.3
--- pcre3-8.12/doc/pcresyntax.3 2010-11-21 17:59:50.000000000 +0000
+++ pcre3-8.31/doc/pcresyntax.3 2012-05-26 14:21:10.000000000 +0000
@@ -1,4 +1,4 @@
-.TH PCRESYNTAX 3
+.TH PCRESYNTAX 3 "10 January 2012" "PCRE 8.30"
.SH NAME
PCRE - Perl-compatible regular expressions
.SH "PCRE REGULAR EXPRESSION SYNTAX SUMMARY"
@@ -9,8 +9,7 @@
.\" HREF
\fBpcrepattern\fP
.\"
-documentation. This document contains just a quick-reference summary of the
-syntax.
+documentation. This document contains a quick-reference summary of the syntax.
.
.
.SH "QUOTING"
@@ -26,7 +25,7 @@
\ea alarm, that is, the BEL character (hex 07)
\ecx "control-x", where x is any ASCII character
\ee escape (hex 1B)
- \ef formfeed (hex 0C)
+ \ef form feed (hex 0C)
\en newline (hex 0A)
\er carriage return (hex 0D)
\et tab (hex 09)
@@ -40,25 +39,25 @@
.sp
. any character except newline;
in dotall mode, any character whatsoever
- \eC one byte, even in UTF-8 mode (best avoided)
+ \eC one data unit, even in UTF mode (best avoided)
\ed a decimal digit
\eD a character that is not a decimal digit
- \eh a horizontal whitespace character
- \eH a character that is not a horizontal whitespace character
+ \eh a horizontal white space character
+ \eH a character that is not a horizontal white space character
\eN a character that is not a newline
\ep{\fIxx\fP} a character with the \fIxx\fP property
\eP{\fIxx\fP} a character without the \fIxx\fP property
\eR a newline sequence
- \es a whitespace character
- \eS a character that is not a whitespace character
- \ev a vertical whitespace character
- \eV a character that is not a vertical whitespace character
+ \es a white space character
+ \eS a character that is not a white space character
+ \ev a vertical white space character
+ \eV a character that is not a vertical white space character
\ew a "word" character
\eW a "non-word" character
\eX an extended Unicode sequence
.sp
In PCRE, by default, \ed, \eD, \es, \eS, \ew, and \eW recognize only ASCII
-characters, even in UTF-8 mode. However, this can be changed by setting the
+characters, even in a UTF mode. However, this can be changed by setting the
PCRE_UCP option.
.
.
@@ -128,13 +127,16 @@
Avestan,
Balinese,
Bamum,
+Batak,
Bengali,
Bopomofo,
+Brahmi,
Braille,
Buginese,
Buhid,
Canadian_Aboriginal,
Carian,
+Chakma,
Cham,
Cherokee,
Common,
@@ -177,7 +179,11 @@
Lycian,
Lydian,
Malayalam,
+Mandaic,
Meetei_Mayek,
+Meroitic_Cursive,
+Meroitic_Hieroglyphs,
+Miao,
Mongolian,
Myanmar,
New_Tai_Lue,
@@ -196,8 +202,10 @@
Runic,
Samaritan,
Saurashtra,
+Sharada,
Shavian,
Sinhala,
+Sora_Sompeng,
Sundanese,
Syloti_Nagri,
Syriac,
@@ -206,6 +214,7 @@
Tai_Le,
Tai_Tham,
Tai_Viet,
+Takri,
Tamil,
Telugu,
Thaana,
@@ -236,7 +245,7 @@
lower lower case letter
print printing, including space
punct printing, excluding alphanumeric
- space whitespace
+ space white space
upper upper case letter
word same as \ew
xdigit hexadecimal digit
@@ -337,7 +346,8 @@
newline-setting options with similar syntax:
.sp
(*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
- (*UTF8) set UTF-8 mode (PCRE_UTF8)
+ (*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8)
+ (*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16)
(*UCP) set PCRE_UCP (use Unicode properties for \ed etc)
.
.
@@ -411,6 +421,7 @@
.sp
(*ACCEPT) force successful match
(*FAIL) force backtrack; synonym (*F)
+ (*MARK:NAME) set name to be passed back; synonym (*:NAME)
.sp
The following act only when a subsequent match failure causes a backtrack to
reach them. They all force a match failure, but they differ in what happens
@@ -419,15 +430,19 @@
.sp
(*COMMIT) overall failure, no advance of starting point
(*PRUNE) advance to next starting character
- (*SKIP) advance start to current matching position
+ (*PRUNE:NAME) equivalent to (*MARK:NAME)(*PRUNE)
+ (*SKIP) advance to current matching position
+ (*SKIP:NAME) advance to position corresponding to an earlier
+ (*MARK:NAME); if not found, the (*SKIP) is ignored
(*THEN) local failure, backtrack to next alternation
+ (*THEN:NAME) equivalent to (*MARK:NAME)(*THEN)
.
.
.SH "NEWLINE CONVENTIONS"
.rs
.sp
These are recognized only at the very start of the pattern or after a
-(*BSR_...) or (*UTF8) or (*UCP) option.
+(*BSR_...), (*UTF8), (*UTF16) or (*UCP) option.
.sp
(*CR) carriage return only
(*LF) linefeed only
@@ -440,7 +455,7 @@
.rs
.sp
These are recognized only at the very start of the pattern or after a
-(*...) option that sets the newline convention or UTF-8 or UCP mode.
+(*...) option that sets the newline convention or a UTF or UCP mode.
.sp
(*BSR_ANYCRLF) CR, LF, or CRLF
(*BSR_UNICODE) any Unicode newline sequence
@@ -474,6 +489,6 @@
.rs
.sp
.nf
-Last updated: 21 November 2010
-Copyright (c) 1997-2010 University of Cambridge.
+Last updated: 10 January 2012
+Copyright (c) 1997-2012 University of Cambridge.
.fi
diff -Nru pcre3-8.12/doc/pcretest.1 pcre3-8.31/doc/pcretest.1
--- pcre3-8.12/doc/pcretest.1 2010-11-24 17:38:33.000000000 +0000
+++ pcre3-8.31/doc/pcretest.1 2012-06-02 10:55:17.000000000 +0000
@@ -1,10 +1,10 @@
-.TH PCRETEST 1
+.TH PCRETEST 1 "21 February 2012" "PCRE 8.31"
.SH NAME
pcretest - a program for testing Perl-compatible regular expressions.
.SH SYNOPSIS
.rs
.sp
-.B pcretest "[options] [source] [destination]"
+.B pcretest "[options] [input file [output file]]"
.sp
\fBpcretest\fP was written as a test program for the PCRE regular expression
library itself, but it can also be used for experimenting with regular
@@ -18,67 +18,151 @@
.\" HREF
\fBpcreapi\fP
.\"
-documentation.
+and
+.\" HREF
+\fBpcre16\fP
+.\"
+documentation. The input for \fBpcretest\fP is a sequence of regular expression
+patterns and strings to be matched, as described below. The output shows the
+result of each match. Options on the command line and the patterns control PCRE
+options and exactly what is output.
+.
+.
+.SH "PCRE's 8-BIT and 16-BIT LIBRARIES"
+.rs
+.sp
+From release 8.30, two separate PCRE libraries can be built. The original one
+supports 8-bit character strings, whereas the newer 16-bit library supports
+character strings encoded in 16-bit units. The \fBpcretest\fP program can be
+used to test both libraries. However, it is itself still an 8-bit program,
+reading 8-bit input and writing 8-bit output. When testing the 16-bit library,
+the patterns and data strings are converted to 16-bit format before being
+passed to the PCRE library functions. Results are converted to 8-bit for
+output.
+.P
+References to functions and structures of the form \fBpcre[16]_xx\fP below
+mean "\fBpcre_xx\fP when using the 8-bit library or \fBpcre16_xx\fP when using
+the 16-bit library".
.
.
-.SH OPTIONS
+.SH "COMMAND LINE OPTIONS"
.rs
.TP 10
+\fB-16\fP
+If both the 8-bit and the 16-bit libraries have been built, this option causes
+the 16-bit library to be used. If only the 16-bit library has been built, this
+is the default (so has no effect). If only the 8-bit library has been built,
+this option causes an error.
+.TP 10
\fB-b\fP
-Behave as if each regex has the \fB/B\fP (show bytecode) modifier; the internal
-form is output after compilation.
+Behave as if each pattern has the \fB/B\fP (show byte code) modifier; the
+internal form is output after compilation.
.TP 10
\fB-C\fP
Output the version number of the PCRE library, and all available information
-about the optional features that are included, and then exit.
+about the optional features that are included, and then exit. All other options
+are ignored.
+.TP 10
+\fB-C\fP \fIoption\fP
+Output information about a specific build-time option, then exit. This
+functionality is intended for use in scripts such as \fBRunTest\fP. The
+following options output the value indicated:
+.sp
+ linksize the internal link size (2, 3, or 4)
+ newline the default newline setting:
+ CR, LF, CRLF, ANYCRLF, or ANY
+.sp
+The following options output 1 for true or zero for false:
+.sp
+ jit just-in-time support is available
+ pcre16 the 16-bit library was built
+ pcre8 the 8-bit library was built
+ ucp Unicode property support is available
+ utf UTF-8 and/or UTF-16 support is available
.TP 10
\fB-d\fP
-Behave as if each regex has the \fB/D\fP (debug) modifier; the internal
+Behave as if each pattern has the \fB/D\fP (debug) modifier; the internal
form and information about the compiled pattern is output after compilation;
\fB-d\fP is equivalent to \fB-b -i\fP.
.TP 10
\fB-dfa\fP
Behave as if each data line contains the \eD escape sequence; this causes the
-alternative matching function, \fBpcre_dfa_exec()\fP, to be used instead of the
-standard \fBpcre_exec()\fP function (more detail is given below).
+alternative matching function, \fBpcre[16]_dfa_exec()\fP, to be used instead of
+the standard \fBpcre[16]_exec()\fP function (more detail is given below).
.TP 10
\fB-help\fP
Output a brief summary these options and then exit.
.TP 10
\fB-i\fP
-Behave as if each regex has the \fB/I\fP modifier; information about the
+Behave as if each pattern has the \fB/I\fP modifier; information about the
compiled pattern is given after compilation.
.TP 10
\fB-M\fP
Behave as if each data line contains the \eM escape sequence; this causes
PCRE to discover the minimum MATCH_LIMIT and MATCH_LIMIT_RECURSION settings by
-calling \fBpcre_exec()\fP repeatedly with different limits.
+calling \fBpcre[16]_exec()\fP repeatedly with different limits.
.TP 10
\fB-m\fP
Output the size of each compiled pattern after it has been compiled. This is
-equivalent to adding \fB/M\fP to each regular expression. For compatibility
-with earlier versions of pcretest, \fB-s\fP is a synonym for \fB-m\fP.
+equivalent to adding \fB/M\fP to each regular expression. The size is given in
+bytes for both libraries.
.TP 10
\fB-o\fP \fIosize\fP
Set the number of elements in the output vector that is used when calling
-\fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP to be \fIosize\fP. The default value
-is 45, which is enough for 14 capturing subexpressions for \fBpcre_exec()\fP or
-22 different matches for \fBpcre_dfa_exec()\fP. The vector size can be
-changed for individual matching calls by including \eO in the data line (see
-below).
+\fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP to be \fIosize\fP. The
+default value is 45, which is enough for 14 capturing subexpressions for
+\fBpcre[16]_exec()\fP or 22 different matches for \fBpcre[16]_dfa_exec()\fP.
+The vector size can be changed for individual matching calls by including \eO
+in the data line (see below).
.TP 10
\fB-p\fP
-Behave as if each regex has the \fB/P\fP modifier; the POSIX wrapper API is
+Behave as if each pattern has the \fB/P\fP modifier; the POSIX wrapper API is
used to call PCRE. None of the other options has any effect when \fB-p\fP is
-set.
+set. This option can be used only with the 8-bit library.
.TP 10
\fB-q\fP
Do not output the version number of \fBpcretest\fP at the start of execution.
.TP 10
\fB-S\fP \fIsize\fP
-On Unix-like systems, set the size of the runtime stack to \fIsize\fP
+On Unix-like systems, set the size of the run-time stack to \fIsize\fP
megabytes.
.TP 10
+\fB-s\fP or \fB-s+\fP
+Behave as if each pattern has the \fB/S\fP modifier; in other words, force each
+pattern to be studied. If \fB-s+\fP is used, all the JIT compile options are
+passed to \fBpcre[16]_study()\fP, causing just-in-time optimization to be set
+up if it is available, for both full and partial matching. Specific JIT compile
+options can be selected by following \fB-s+\fP with a digit in the range 1 to
+7, which selects the JIT compile modes as follows:
+.sp
+ 1 normal match only
+ 2 soft partial match only
+ 3 normal match and soft partial match
+ 4 hard partial match only
+ 6 soft and hard partial match
+ 7 all three modes (default)
+.sp
+If \fB-s++\fP is used instead of \fB-s+\fP (with or without a following digit),
+the text "(JIT)" is added to the first output line after a match or no match
+when JIT-compiled code was actually used.
+.P
+If the \fB/I\fP or \fB/D\fP option is present on a pattern (requesting output
+about the compiled pattern), information about the result of studying is not
+included when studying is caused only by \fB-s\fP and neither \fB-i\fP nor
+\fB-d\fP is present on the command line. This behaviour means that the output
+from tests that are run with and without \fB-s\fP should be identical, except
+when options that output information about the actual running of a match are
+set.
+.sp
+The \fB-M\fP, \fB-t\fP, and \fB-tm\fP options, which give information about
+resources used, are likely to produce different output with and without
+\fB-s\fP. Output may also differ if the \fB/C\fP option is present on an
+individual pattern. This uses callouts to trace the the matching process, and
+this may be different between studied and non-studied patterns. If the pattern
+contains (*MARK) items there may also be differences, for the same reason. The
+\fB-s\fP command line option can be overridden for specific patterns that
+should never be studied (see the \fB/S\fP pattern modifier below).
+.TP 10
\fB-t\fP
Run each compile, study, and match many times with a timer, and output
resulting time per compile or match (in milliseconds). Do not set \fB-m\fP with
@@ -154,13 +238,13 @@
A pattern may be followed by any number of modifiers, which are mostly single
characters. Following Perl usage, these are referred to below as, for example,
"the \fB/i\fP modifier", even though the delimiter of the pattern need not
-always be a slash, and no slash is used when writing modifiers. Whitespace may
+always be a slash, and no slash is used when writing modifiers. White space may
appear between the final pattern delimiter and the first modifier, and between
the modifiers themselves.
.P
The \fB/i\fP, \fB/m\fP, \fB/s\fP, and \fB/x\fP modifiers set the PCRE_CASELESS,
PCRE_MULTILINE, PCRE_DOTALL, or PCRE_EXTENDED options, respectively, when
-\fBpcre_compile()\fP is called. These four modifier letters have the same
+\fBpcre[16]_compile()\fP is called. These four modifier letters have the same
effect as they do in Perl. For example:
.sp
/caseless/i
@@ -168,8 +252,12 @@
The following table shows additional modifiers for setting PCRE compile-time
options that do not correspond to anything in Perl:
.sp
- \fB/8\fP PCRE_UTF8
- \fB/?\fP PCRE_NO_UTF8_CHECK
+ \fB/8\fP PCRE_UTF8 ) when using the 8-bit
+ \fB/?\fP PCRE_NO_UTF8_CHECK ) library
+.sp
+ \fB/8\fP PCRE_UTF16 ) when using the 16-bit
+ \fB/?\fP PCRE_NO_UTF16_CHECK ) library
+.sp
\fB/A\fP PCRE_ANCHORED
\fB/C\fP PCRE_AUTO_CALLOUT
\fB/E\fP PCRE_DOLLAR_ENDONLY
@@ -190,15 +278,17 @@
\fB/\fP PCRE_BSR_UNICODE
.sp
The modifiers that are enclosed in angle brackets are literal strings as shown,
-including the angle brackets, but the letters can be in either case. This
-example sets multiline matching with CRLF as the line ending sequence:
+including the angle brackets, but the letters within can be in either case.
+This example sets multiline matching with CRLF as the line ending sequence:
.sp
- /^abc/m
+ /^abc/m
.sp
-As well as turning on the PCRE_UTF8 option, the \fB/8\fP modifier also causes
-any non-printing characters in output strings to be printed using the
-\ex{hh...} notation if they are valid UTF-8 sequences. Full details of the PCRE
-options are given in the
+As well as turning on the PCRE_UTF8/16 option, the \fB/8\fP modifier causes
+all non-printing characters in output strings to be printed using the
+\ex{hh...} notation. Otherwise, those less than 0x100 are output in hex without
+the curly brackets.
+.P
+Full details of the PCRE options are given in the
.\" HREF
\fBpcreapi\fP
.\"
@@ -212,13 +302,13 @@
by the \fB/g\fP or \fB/G\fP modifier. After finding a match, PCRE is called
again to search the remainder of the subject string. The difference between
\fB/g\fP and \fB/G\fP is that the former uses the \fIstartoffset\fP argument to
-\fBpcre_exec()\fP to start searching at a new point within the entire string
-(which is in effect what Perl does), whereas the latter passes over a shortened
-substring. This makes a difference to the matching process if the pattern
-begins with a lookbehind assertion (including \eb or \eB).
+\fBpcre[16]_exec()\fP to start searching at a new point within the entire
+string (which is in effect what Perl does), whereas the latter passes over a
+shortened substring. This makes a difference to the matching process if the
+pattern begins with a lookbehind assertion (including \eb or \eB).
.P
-If any call to \fBpcre_exec()\fP in a \fB/g\fP or \fB/G\fP sequence matches an
-empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART and
+If any call to \fBpcre[16]_exec()\fP in a \fB/g\fP or \fB/G\fP sequence matches
+an empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART and
PCRE_ANCHORED flags set in order to search for another, non-empty, match at the
same point. If this second match fails, the start offset is advanced, and the
normal match is retried. This imitates the way Perl handles such cases when
@@ -235,42 +325,53 @@
operates.
.P
The \fB/+\fP modifier requests that as well as outputting the substring that
-matched the entire pattern, pcretest should in addition output the remainder of
-the subject string. This is useful for tests where the subject contains
-multiple copies of the same substring.
+matched the entire pattern, \fBpcretest\fP should in addition output the
+remainder of the subject string. This is useful for tests where the subject
+contains multiple copies of the same substring. If the \fB+\fP modifier appears
+twice, the same action is taken for captured substrings. In each case the
+remainder is output on the following line with a plus character following the
+capture number. Note that this modifier must not immediately follow the /S
+modifier because /S+ and /S++ have other meanings.
+.P
+The \fB/=\fP modifier requests that the values of all potential captured
+parentheses be output after a match. By default, only those up to the highest
+one actually used in the match are output (corresponding to the return code
+from \fBpcre[16]_exec()\fP). Values in the offsets vector corresponding to
+higher numbers should be set to -1, and these are output as "". This
+modifier gives a way of checking that this is happening.
.P
The \fB/B\fP modifier is a debugging feature. It requests that \fBpcretest\fP
-output a representation of the compiled byte code after compilation. Normally
-this information contains length and offset values; however, if \fB/Z\fP is
-also present, this data is replaced by spaces. This is a special feature for
-use in the automatic test scripts; it ensures that the same output is generated
-for different internal link sizes.
+output a representation of the compiled code after compilation. Normally this
+information contains length and offset values; however, if \fB/Z\fP is also
+present, this data is replaced by spaces. This is a special feature for use in
+the automatic test scripts; it ensures that the same output is generated for
+different internal link sizes.
.P
The \fB/D\fP modifier is a PCRE debugging feature, and is equivalent to
\fB/BI\fP, that is, both the \fB/B\fP and the \fB/I\fP modifiers.
.P
The \fB/F\fP modifier causes \fBpcretest\fP to flip the byte order of the
-fields in the compiled pattern that contain 2-byte and 4-byte numbers. This
-facility is for testing the feature in PCRE that allows it to execute patterns
-that were compiled on a host with a different endianness. This feature is not
-available when the POSIX interface to PCRE is being used, that is, when the
-\fB/P\fP pattern modifier is specified. See also the section about saving and
-reloading compiled patterns below.
+2-byte and 4-byte fields in the compiled pattern. This facility is for testing
+the feature in PCRE that allows it to execute patterns that were compiled on a
+host with a different endianness. This feature is not available when the POSIX
+interface to PCRE is being used, that is, when the \fB/P\fP pattern modifier is
+specified. See also the section about saving and reloading compiled patterns
+below.
.P
The \fB/I\fP modifier requests that \fBpcretest\fP output information about the
compiled pattern (whether it is anchored, has a fixed first character, and
-so on). It does this by calling \fBpcre_fullinfo()\fP after compiling a
+so on). It does this by calling \fBpcre[16]_fullinfo()\fP after compiling a
pattern. If the pattern is studied, the results of that are also output.
.P
The \fB/K\fP modifier requests \fBpcretest\fP to show names from backtracking
-control verbs that are returned from calls to \fBpcre_exec()\fP. It causes
-\fBpcretest\fP to create a \fBpcre_extra\fP block if one has not already been
-created by a call to \fBpcre_study()\fP, and to set the PCRE_EXTRA_MARK flag
-and the \fBmark\fP field within it, every time that \fBpcre_exec()\fP is
-called. If the variable that the \fBmark\fP field points to is non-NULL for a
-match, non-match, or partial match, \fBpcretest\fP prints the string to which
-it points. For a match, this is shown on a line by itself, tagged with "MK:".
-For a non-match it is added to the message.
+control verbs that are returned from calls to \fBpcre[16]_exec()\fP. It causes
+\fBpcretest\fP to create a \fBpcre[16]_extra\fP block if one has not already
+been created by a call to \fBpcre[16]_study()\fP, and to set the
+PCRE_EXTRA_MARK flag and the \fBmark\fP field within it, every time that
+\fBpcre[16]_exec()\fP is called. If the variable that the \fBmark\fP field
+points to is non-NULL for a match, non-match, or partial match, \fBpcretest\fP
+prints the string to which it points. For a match, this is shown on a line by
+itself, tagged with "MK:". For a non-match it is added to the message.
.P
The \fB/L\fP modifier must be followed directly by the name of a locale, for
example,
@@ -278,22 +379,58 @@
/pattern/Lfr_FR
.sp
For this reason, it must be the last modifier. The given locale is set,
-\fBpcre_maketables()\fP is called to build a set of character tables for the
-locale, and this is then passed to \fBpcre_compile()\fP when compiling the
-regular expression. Without an \fB/L\fP (or \fB/T\fP) modifier, NULL is passed
-as the tables pointer; that is, \fB/L\fP applies only to the expression on
-which it appears.
-.P
-The \fB/M\fP modifier causes the size of memory block used to hold the compiled
-pattern to be output.
-.P
-The \fB/S\fP modifier causes \fBpcre_study()\fP to be called after the
-expression has been compiled, and the results used when the expression is
-matched.
+\fBpcre[16]_maketables()\fP is called to build a set of character tables for
+the locale, and this is then passed to \fBpcre[16]_compile()\fP when compiling
+the regular expression. Without an \fB/L\fP (or \fB/T\fP) modifier, NULL is
+passed as the tables pointer; that is, \fB/L\fP applies only to the expression
+on which it appears.
+.P
+The \fB/M\fP modifier causes the size in bytes of the memory block used to hold
+the compiled pattern to be output. This does not include the size of the
+\fBpcre[16]\fP block; it is just the actual compiled data. If the pattern is
+successfully studied with the PCRE_STUDY_JIT_COMPILE option, the size of the
+JIT compiled code is also output.
+.P
+If the \fB/S\fP modifier appears once, it causes \fBpcre[16]_study()\fP to be
+called after the expression has been compiled, and the results used when the
+expression is matched. If \fB/S\fP appears twice, it suppresses studying, even
+if it was requested externally by the \fB-s\fP command line option. This makes
+it possible to specify that certain patterns are always studied, and others are
+never studied, independently of \fB-s\fP. This feature is used in the test
+files in a few cases where the output is different when the pattern is studied.
+.P
+If the \fB/S\fP modifier is immediately followed by a + character, the call to
+\fBpcre[16]_study()\fP is made with all the JIT study options, requesting
+just-in-time optimization support if it is available, for both normal and
+partial matching. If you want to restrict the JIT compiling modes, you can
+follow \fB/S+\fP with a digit in the range 1 to 7:
+.sp
+ 1 normal match only
+ 2 soft partial match only
+ 3 normal match and soft partial match
+ 4 hard partial match only
+ 6 soft and hard partial match
+ 7 all three modes (default)
+.sp
+If \fB/S++\fP is used instead of \fB/S+\fP (with or without a following digit),
+the text "(JIT)" is added to the first output line after a match or no match
+when JIT-compiled code was actually used.
+.P
+Note that there is also an independent \fB/+\fP modifier; it must not be given
+immediately after \fB/S\fP or \fB/S+\fP because this will be misinterpreted.
+.P
+If JIT studying is successful, the compiled JIT code will automatically be used
+when \fBpcre[16]_exec()\fP is run, except when incompatible run-time options
+are specified. For more details, see the
+.\" HREF
+\fBpcrejit\fP
+.\"
+documentation. See also the \fB\eJ\fP escape sequence below for a way of
+setting the size of the JIT stack.
.P
The \fB/T\fP modifier must be followed by a single digit. It causes a specific
-set of built-in character tables to be passed to \fBpcre_compile()\fP. It is
-used in the standard PCRE tests to check behaviour with different character
+set of built-in character tables to be passed to \fBpcre[16]_compile()\fP. It
+is used in the standard PCRE tests to check behaviour with different character
tables. The digit specifies the tables as follows:
.sp
0 the default ASCII tables, as distributed in
@@ -308,8 +445,9 @@
.rs
.sp
The \fB/P\fP modifier causes \fBpcretest\fP to call PCRE via the POSIX wrapper
-API rather than its native API. When \fB/P\fP is set, the following modifiers
-set options for the \fBregcomp()\fP function:
+API rather than its native API. This supports only the 8-bit library. When
+\fB/P\fP is set, the following modifiers set options for the \fBregcomp()\fP
+function:
.sp
/i REG_ICASE
/m REG_NEWLINE
@@ -326,9 +464,9 @@
.SH "DATA LINES"
.rs
.sp
-Before each data line is passed to \fBpcre_exec()\fP, leading and trailing
-whitespace is removed, and it is then scanned for \e escapes. Some of these are
-pretty esoteric features, intended for checking out some of the more
+Before each data line is passed to \fBpcre[16]_exec()\fP, leading and trailing
+white space is removed, and it is then scanned for \e escapes. Some of these
+are pretty esoteric features, intended for checking out some of the more
complicated features of PCRE. If you are just testing "ordinary" regular
expressions, you probably don't need any of these. The following escapes are
recognized:
@@ -336,7 +474,7 @@
\ea alarm (BEL, \ex07)
\eb backspace (\ex08)
\ee escape (\ex27)
- \ef formfeed (\ex0c)
+ \ef form feed (\ex0c)
\en newline (\ex0a)
.\" JOIN
\eqdd set the PCRE_MATCH_LIMIT limit to dd
@@ -344,23 +482,21 @@
\er carriage return (\ex0d)
\et tab (\ex09)
\ev vertical tab (\ex0b)
- \ennn octal character (up to 3 octal digits)
- always a byte unless > 255 in UTF-8 mode
+ \ennn octal character (up to 3 octal digits); always
+ a byte unless > 255 in UTF-8 or 16-bit mode
\exhh hexadecimal byte (up to 2 hex digits)
+ \ex{hh...} hexadecimal character (any number of hex digits)
.\" JOIN
- \ex{hh...} hexadecimal character, any number of digits
- in UTF-8 mode
-.\" JOIN
- \eA pass the PCRE_ANCHORED option to \fBpcre_exec()\fP
- or \fBpcre_dfa_exec()\fP
+ \eA pass the PCRE_ANCHORED option to \fBpcre[16]_exec()\fP
+ or \fBpcre[16]_dfa_exec()\fP
.\" JOIN
- \eB pass the PCRE_NOTBOL option to \fBpcre_exec()\fP
- or \fBpcre_dfa_exec()\fP
+ \eB pass the PCRE_NOTBOL option to \fBpcre[16]_exec()\fP
+ or \fBpcre[16]_dfa_exec()\fP
.\" JOIN
- \eCdd call pcre_copy_substring() for substring dd
+ \eCdd call pcre[16]_copy_substring() for substring dd
after a successful match (number less than 32)
.\" JOIN
- \eCname call pcre_copy_named_substring() for substring
+ \eCname call pcre[16]_copy_named_substring() for substring
"name" after a successful match (name termin-
ated by next non alphanumeric character)
.\" JOIN
@@ -376,72 +512,82 @@
.\" JOIN
\eC*n pass the number n (may be negative) as callout
data; this is used as the callout return value
- \eD use the \fBpcre_dfa_exec()\fP match function
- \eF only shortest match for \fBpcre_dfa_exec()\fP
+ \eD use the \fBpcre[16]_dfa_exec()\fP match function
+ \eF only shortest match for \fBpcre[16]_dfa_exec()\fP
.\" JOIN
- \eGdd call pcre_get_substring() for substring dd
+ \eGdd call pcre[16]_get_substring() for substring dd
after a successful match (number less than 32)
.\" JOIN
- \eGname call pcre_get_named_substring() for substring
+ \eGname call pcre[16]_get_named_substring() for substring
"name" after a successful match (name termin-
ated by next non-alphanumeric character)
.\" JOIN
- \eL call pcre_get_substringlist() after a
+ \eJdd set up a JIT stack of dd kilobytes maximum (any
+ number of digits)
+.\" JOIN
+ \eL call pcre[16]_get_substringlist() after a
successful match
.\" JOIN
\eM discover the minimum MATCH_LIMIT and
MATCH_LIMIT_RECURSION settings
.\" JOIN
- \eN pass the PCRE_NOTEMPTY option to \fBpcre_exec()\fP
- or \fBpcre_dfa_exec()\fP; if used twice, pass the
+ \eN pass the PCRE_NOTEMPTY option to \fBpcre[16]_exec()\fP
+ or \fBpcre[16]_dfa_exec()\fP; if used twice, pass the
PCRE_NOTEMPTY_ATSTART option
.\" JOIN
\eOdd set the size of the output vector passed to
- \fBpcre_exec()\fP to dd (any number of digits)
+ \fBpcre[16]_exec()\fP to dd (any number of digits)
.\" JOIN
- \eP pass the PCRE_PARTIAL_SOFT option to \fBpcre_exec()\fP
- or \fBpcre_dfa_exec()\fP; if used twice, pass the
+ \eP pass the PCRE_PARTIAL_SOFT option to \fBpcre[16]_exec()\fP
+ or \fBpcre[16]_dfa_exec()\fP; if used twice, pass the
PCRE_PARTIAL_HARD option
.\" JOIN
\eQdd set the PCRE_MATCH_LIMIT_RECURSION limit to dd
(any number of digits)
- \eR pass the PCRE_DFA_RESTART option to \fBpcre_dfa_exec()\fP
+ \eR pass the PCRE_DFA_RESTART option to \fBpcre[16]_dfa_exec()\fP
\eS output details of memory get/free calls during matching
.\" JOIN
- \eY pass the PCRE_NO_START_OPTIMIZE option to \fBpcre_exec()\fP
- or \fBpcre_dfa_exec()\fP
+ \eY pass the PCRE_NO_START_OPTIMIZE option to \fBpcre[16]_exec()\fP
+ or \fBpcre[16]_dfa_exec()\fP
.\" JOIN
- \eZ pass the PCRE_NOTEOL option to \fBpcre_exec()\fP
- or \fBpcre_dfa_exec()\fP
+ \eZ pass the PCRE_NOTEOL option to \fBpcre[16]_exec()\fP
+ or \fBpcre[16]_dfa_exec()\fP
.\" JOIN
- \e? pass the PCRE_NO_UTF8_CHECK option to
- \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP
+ \e? pass the PCRE_NO_UTF[8|16]_CHECK option to
+ \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP
.\" JOIN
\e>dd start the match at offset dd (optional "-"; then
any number of digits); this sets the \fIstartoffset\fP
- argument for \fBpcre_exec()\fP or \fBpcre_dfa_exec()\fP
+ argument for \fBpcre[16]_exec()\fP or \fBpcre[16]_dfa_exec()\fP
.\" JOIN
- \e pass the PCRE_NEWLINE_CR option to \fBpcre_exec()\fP
- or \fBpcre_dfa_exec()\fP
+ \e pass the PCRE_NEWLINE_CR option to \fBpcre[16]_exec()\fP
+ or \fBpcre[16]_dfa_exec()\fP
.\" JOIN
- \e pass the PCRE_NEWLINE_LF option to \fBpcre_exec()\fP
- or \fBpcre_dfa_exec()\fP
+ \e pass the PCRE_NEWLINE_LF option to \fBpcre[16]_exec()\fP
+ or \fBpcre[16]_dfa_exec()\fP
.\" JOIN
- \e pass the PCRE_NEWLINE_CRLF option to \fBpcre_exec()\fP
- or \fBpcre_dfa_exec()\fP
+ \e pass the PCRE_NEWLINE_CRLF option to \fBpcre[16]_exec()\fP
+ or \fBpcre[16]_dfa_exec()\fP
.\" JOIN
- \e pass the PCRE_NEWLINE_ANYCRLF option to \fBpcre_exec()\fP
- or \fBpcre_dfa_exec()\fP
+ \e pass the PCRE_NEWLINE_ANYCRLF option to \fBpcre[16]_exec()\fP
+ or \fBpcre[16]_dfa_exec()\fP
.\" JOIN
- \e pass the PCRE_NEWLINE_ANY option to \fBpcre_exec()\fP
- or \fBpcre_dfa_exec()\fP
+ \e pass the PCRE_NEWLINE_ANY option to \fBpcre[16]_exec()\fP
+ or \fBpcre[16]_dfa_exec()\fP
.sp
-Note that \exhh always specifies one byte, even in UTF-8 mode; this makes it
-possible to construct invalid UTF-8 sequences for testing purposes. On the
-other hand, \ex{hh} is interpreted as a UTF-8 character in UTF-8 mode,
-generating more than one byte if the value is greater than 127. When not in
-UTF-8 mode, it generates one byte for values less than 256, and causes an error
-for greater values.
+The use of \ex{hh...} is not dependent on the use of the \fB/8\fP modifier on
+the pattern. It is recognized always. There may be any number of hexadecimal
+digits inside the braces; invalid values provoke error messages.
+.P
+Note that \exhh specifies one byte rather than one character in UTF-8 mode;
+this makes it possible to construct invalid UTF-8 sequences for testing
+purposes. On the other hand, \ex{hh} is interpreted as a UTF-8 character in
+UTF-8 mode, generating more than one byte if the value is greater than 127.
+When testing the 8-bit library not in UTF-8 mode, \ex{hh} generates one byte
+for values less than 256, and causes an error for greater values.
+.P
+In UTF-16 mode, all 4-digit \ex{hhhh} values are accepted. This makes it
+possible to construct invalid UTF-16 sequences for testing purposes.
.P
The escapes that specify line ending sequences are literal strings, exactly as
shown. No more than one newline setting should be present in any data line.
@@ -451,42 +597,43 @@
passing an empty line as data, since a real empty line terminates the data
input.
.P
-If \eM is present, \fBpcretest\fP calls \fBpcre_exec()\fP several times, with
-different values in the \fImatch_limit\fP and \fImatch_limit_recursion\fP
-fields of the \fBpcre_extra\fP data structure, until it finds the minimum
-numbers for each parameter that allow \fBpcre_exec()\fP to complete. The
-\fImatch_limit\fP number is a measure of the amount of backtracking that takes
-place, and checking it out can be instructive. For most simple matches, the
-number is quite small, but for patterns with very large numbers of matching
-possibilities, it can become large very quickly with increasing length of
-subject string. The \fImatch_limit_recursion\fP number is a measure of how much
-stack (or, if PCRE is compiled with NO_RECURSE, how much heap) memory is needed
-to complete the match attempt.
+The \fB\eJ\fP escape provides a way of setting the maximum stack size that is
+used by the just-in-time optimization code. It is ignored if JIT optimization
+is not being used. Providing a stack that is larger than the default 32K is
+necessary only for very complicated patterns.
+.P
+If \eM is present, \fBpcretest\fP calls \fBpcre[16]_exec()\fP several times,
+with different values in the \fImatch_limit\fP and \fImatch_limit_recursion\fP
+fields of the \fBpcre[16]_extra\fP data structure, until it finds the minimum
+numbers for each parameter that allow \fBpcre[16]_exec()\fP to complete without
+error. Because this is testing a specific feature of the normal interpretive
+\fBpcre[16]_exec()\fP execution, the use of any JIT optimization that might
+have been set up by the \fB/S+\fP qualifier of \fB-s+\fP option is disabled.
+.P
+The \fImatch_limit\fP number is a measure of the amount of backtracking
+that takes place, and checking it out can be instructive. For most simple
+matches, the number is quite small, but for patterns with very large numbers of
+matching possibilities, it can become large very quickly with increasing length
+of subject string. The \fImatch_limit_recursion\fP number is a measure of how
+much stack (or, if PCRE is compiled with NO_RECURSE, how much heap) memory is
+needed to complete the match attempt.
.P
When \eO is used, the value specified may be higher or lower than the size set
by the \fB-O\fP command line option (or defaulted to 45); \eO applies only to
-the call of \fBpcre_exec()\fP for the line in which it appears.
+the call of \fBpcre[16]_exec()\fP for the line in which it appears.
.P
If the \fB/P\fP modifier was present on the pattern, causing the POSIX wrapper
API to be used, the only option-setting sequences that have any effect are \eB,
\eN, and \eZ, causing REG_NOTBOL, REG_NOTEMPTY, and REG_NOTEOL, respectively,
to be passed to \fBregexec()\fP.
-.P
-The use of \ex{hh...} to represent UTF-8 characters is not dependent on the use
-of the \fB/8\fP modifier on the pattern. It is recognized always. There may be
-any number of hexadecimal digits inside the braces. The result is from one to
-six bytes, encoded according to the original UTF-8 rules of RFC 2279. This
-allows for values in the range 0 to 0x7FFFFFFF. Note that not all of those are
-valid Unicode code points, or indeed valid UTF-8 characters according to the
-later rules in RFC 3629.
.
.
.SH "THE ALTERNATIVE MATCHING FUNCTION"
.rs
.sp
By default, \fBpcretest\fP uses the standard PCRE matching function,
-\fBpcre_exec()\fP to match each data line. From release 6.0, PCRE supports an
-alternative matching function, \fBpcre_dfa_test()\fP, which operates in a
+\fBpcre[16]_exec()\fP to match each data line. PCRE also supports an
+alternative matching function, \fBpcre[16]_dfa_test()\fP, which operates in a
different way, and has some restrictions. The differences between the two
functions are described in the
.\" HREF
@@ -495,7 +642,7 @@
documentation.
.P
If a data line contains the \eD escape sequence, or if the command line
-contains the \fB-dfa\fP option, the alternative matching function is called.
+contains the \fB-dfa\fP option, the alternative matching function is used.
This function finds all possible matches at a given point. If, however, the \eF
escape sequence is present in the data line, it stops after the first match is
found. This is always the shortest possible match.
@@ -505,20 +652,23 @@
.rs
.sp
This section describes the output when the normal matching function,
-\fBpcre_exec()\fP, is being used.
+\fBpcre[16]_exec()\fP, is being used.
.P
-When a match succeeds, pcretest outputs the list of captured substrings that
-\fBpcre_exec()\fP returns, starting with number 0 for the string that matched
-the whole pattern. Otherwise, it outputs "No match" when the return is
+When a match succeeds, \fBpcretest\fP outputs the list of captured substrings
+that \fBpcre[16]_exec()\fP returns, starting with number 0 for the string that
+matched the whole pattern. Otherwise, it outputs "No match" when the return is
PCRE_ERROR_NOMATCH, and "Partial match:" followed by the partially matching
-substring when \fBpcre_exec()\fP returns PCRE_ERROR_PARTIAL. (Note that this is
-the entire substring that was inspected during the partial match; it may
-include characters before the actual match start if a lookbehind assertion,
-\eK, \eb, or \eB was involved.) For any other returns, it outputs the PCRE
-negative error number. Here is an example of an interactive \fBpcretest\fP run.
+substring when \fBpcre[16]_exec()\fP returns PCRE_ERROR_PARTIAL. (Note that
+this is the entire substring that was inspected during the partial match; it
+may include characters before the actual match start if a lookbehind assertion,
+\eK, \eb, or \eB was involved.) For any other return, \fBpcretest\fP outputs
+the PCRE negative error number and a short descriptive phrase. If the error is
+a failed UTF string check, the offset of the start of the failing character and
+the reason code are also output, provided that the size of the output vector is
+at least two. Here is an example of an interactive \fBpcretest\fP run.
.sp
$ pcretest
- PCRE version 7.0 30-Nov-2006
+ PCRE version 8.13 2011-04-30
.sp
re> /^abc(\ed+)/
data> abc123
@@ -527,11 +677,11 @@
data> xyz
No match
.sp
-Note that unset capturing substrings that are not followed by one that is set
-are not returned by \fBpcre_exec()\fP, and are not shown by \fBpcretest\fP. In
-the following example, there are two capturing substrings, but when the first
-data line is matched, the second, unset substring is not shown. An "internal"
-unset substring is shown as "", as for the second data line.
+Unset capturing substrings that are not followed by one that is set are not
+returned by \fBpcre[16]_exec()\fP, and are not shown by \fBpcretest\fP. In the
+following example, there are two capturing substrings, but when the first data
+line is matched, the second, unset substring is not shown. An "internal" unset
+substring is shown as "", as for the second data line.
.sp
re> /(a)|(b)/
data> a
@@ -542,11 +692,12 @@
1:
2: b
.sp
-If the strings contain any non-printing characters, they are output as \e0x
-escapes, or as \ex{...} escapes if the \fB/8\fP modifier was present on the
-pattern. See below for the definition of non-printing characters. If the
-pattern has the \fB/+\fP modifier, the output for substring 0 is followed by
-the the rest of the subject string, identified by "0+" like this:
+If the strings contain any non-printing characters, they are output as \exhh
+escapes if the value is less than 256 and UTF mode is not set. Otherwise they
+are output as \ex{hh...} escapes. See below for the definition of non-printing
+characters. If the pattern has the \fB/+\fP modifier, the output for substring
+0 is followed by the the rest of the subject string, identified by "0+" like
+this:
.sp
re> /cat/+
data> cataract
@@ -565,7 +716,13 @@
0: ipp
1: pp
.sp
-"No match" is output only if the first match attempt fails.
+"No match" is output only if the first match attempt fails. Here is an example
+of a failure message (the offset 4 that is specified by \e>4 is past the end of
+the subject string):
+.sp
+ re> /xyz/
+ data> xyz\e>4
+ Error -24 (bad offset value)
.P
If any of the sequences \fB\eC\fP, \fB\eG\fP, or \fB\eL\fP are present in a
data line that is successfully matched, the substrings extracted by the
@@ -584,7 +741,7 @@
.SH "OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION"
.rs
.sp
-When the alternative matching function, \fBpcre_dfa_exec()\fP, is used (by
+When the alternative matching function, \fBpcre[16]_dfa_exec()\fP, is used (by
means of the \eD escape sequence or the \fB-dfa\fP command line option), the
output consists of a list of all the matches that start at the first point in
the subject where there is at least one match. For example:
@@ -646,15 +803,15 @@
is called during matching. This works with both matching functions. By default,
the called function displays the callout number, the start and current
positions in the text at the callout time, and the next pattern item to be
-tested. For example, the output
+tested. For example:
.sp
--->pqrabcdef
0 ^ ^ \ed
.sp
-indicates that callout number 0 occurred for a match attempt starting at the
-fourth character of the subject string, when the pointer was at the seventh
-character of the data, and when the next pattern item was \ed. Just one
-circumflex is output if the start and current positions are the same.
+This output indicates that callout number 0 occurred for a match attempt
+starting at the fourth character of the subject string, when the pointer was at
+the seventh character of the data, and when the next pattern item was \ed. Just
+one circumflex is output if the start and current positions are the same.
.P
Callouts numbered 255 are assumed to be automatic callouts, inserted as a
result of the \fB/C\fP pattern modifier. In this case, instead of showing the
@@ -670,9 +827,27 @@
+10 ^ ^
0: E*
.sp
+If a pattern contains (*MARK) items, an additional line is output whenever
+a change of latest mark is passed to the callout function. For example:
+.sp
+ re> /a(*MARK:X)bc/C
+ data> abc
+ --->abc
+ +0 ^ a
+ +1 ^^ (*MARK:X)
+ +10 ^^ b
+ Latest Mark: X
+ +11 ^ ^ c
+ +12 ^ ^
+ 0: abc
+.sp
+The mark changes between matching "a" and "b", but stays the same for the rest
+of the match, so nothing more is output. If, as a result of backtracking, the
+mark reverts to being unset, the text "" is output.
+.P
The callout function in \fBpcretest\fP returns zero (carry on matching) by
default, but you can use a \eC item in a data line (as described above) to
-change this.
+change this and other parameters of the callout.
.P
Inserting callouts can be helpful when using \fBpcretest\fP to check
complicated regular expressions. For further information about callouts, see
@@ -702,7 +877,7 @@
.rs
.sp
The facilities described in this section are not available when the POSIX
-inteface to PCRE is being used, that is, when the \fB/P\fP pattern modifier is
+interface to PCRE is being used, that is, when the \fB/P\fP pattern modifier is
specified.
.P
When the POSIX interface is not in use, you can cause \fBpcretest\fP to write a
@@ -716,6 +891,8 @@
\fBpcreprecompile\fP
.\"
documentation for a discussion about saving and re-using compiled patterns.
+Note that if the pattern was successfully studied with JIT optimization, the
+JIT data cannot be saved.
.P
The data that is written is binary. The first eight bytes are the length of the
compiled pattern data followed by the length of the optional study data, each
@@ -723,26 +900,35 @@
there is no study data (either the pattern was not studied, or studying did not
return any data), the second length is zero. The lengths are followed by an
exact copy of the compiled pattern. If there is additional study data, this
-follows immediately after the compiled pattern. After writing the file,
-\fBpcretest\fP expects to read a new pattern.
+(excluding any JIT data) follows immediately after the compiled pattern. After
+writing the file, \fBpcretest\fP expects to read a new pattern.
.P
-A saved pattern can be reloaded into \fBpcretest\fP by specifing < and a file
+A saved pattern can be reloaded into \fBpcretest\fP by specifying < and a file
name instead of a pattern. The name of the file must not contain a < character,
as otherwise \fBpcretest\fP will interpret the line as a pattern delimited by <
characters.
For example:
.sp
re> PCRE_BSR_UNICODE
The modifiers that are enclosed in angle brackets are literal strings
- as shown, including the angle brackets, but the letters can be in
- either case. This example sets multiline matching with CRLF as the line
- ending sequence:
-
- /^abc/m
-
- As well as turning on the PCRE_UTF8 option, the /8 modifier also causes
- any non-printing characters in output strings to be printed using the
- \x{hh...} notation if they are valid UTF-8 sequences. Full details of
- the PCRE options are given in the pcreapi documentation.
+ as shown, including the angle brackets, but the letters within can be
+ in either case. This example sets multiline matching with CRLF as the
+ line ending sequence:
+
+ /^abc/m
+
+ As well as turning on the PCRE_UTF8/16 option, the /8 modifier causes
+ all non-printing characters in output strings to be printed using the
+ \x{hh...} notation. Otherwise, those less than 0x100 are output in hex
+ without the curly brackets.
+
+ Full details of the PCRE options are given in the pcreapi documenta-
+ tion.
Finding all matches in a string
- Searching for all possible matches within each subject string can be
- requested by the /g or /G modifier. After finding a match, PCRE is
+ Searching for all possible matches within each subject string can be
+ requested by the /g or /G modifier. After finding a match, PCRE is
called again to search the remainder of the subject string. The differ-
ence between /g and /G is that the former uses the startoffset argument
- to pcre_exec() to start searching at a new point within the entire
- string (which is in effect what Perl does), whereas the latter passes
- over a shortened substring. This makes a difference to the matching
+ to pcre[16]_exec() to start searching at a new point within the entire
+ string (which is in effect what Perl does), whereas the latter passes
+ over a shortened substring. This makes a difference to the matching
process if the pattern begins with a lookbehind assertion (including \b
or \B).
- If any call to pcre_exec() in a /g or /G sequence matches an empty
- string, the next call is done with the PCRE_NOTEMPTY_ATSTART and
- PCRE_ANCHORED flags set in order to search for another, non-empty,
- match at the same point. If this second match fails, the start offset
- is advanced, and the normal match is retried. This imitates the way
+ If any call to pcre[16]_exec() in a /g or /G sequence matches an empty
+ string, the next call is done with the PCRE_NOTEMPTY_ATSTART and
+ PCRE_ANCHORED flags set in order to search for another, non-empty,
+ match at the same point. If this second match fails, the start offset
+ is advanced, and the normal match is retried. This imitates the way
Perl handles such cases when using the /g modifier or the split() func-
- tion. Normally, the start offset is advanced by one character, but if
- the newline convention recognizes CRLF as a newline, and the current
+ tion. Normally, the start offset is advanced by one character, but if
+ the newline convention recognizes CRLF as a newline, and the current
character is CR followed by LF, an advance of two is used.
Other modifiers
There are yet more modifiers for controlling the way pcretest operates.
- The /+ modifier requests that as well as outputting the substring that
- matched the entire pattern, pcretest should in addition output the
- remainder of the subject string. This is useful for tests where the
- subject contains multiple copies of the same substring.
+ The /+ modifier requests that as well as outputting the substring that
+ matched the entire pattern, pcretest should in addition output the
+ remainder of the subject string. This is useful for tests where the
+ subject contains multiple copies of the same substring. If the + modi-
+ fier appears twice, the same action is taken for captured substrings.
+ In each case the remainder is output on the following line with a plus
+ character following the capture number. Note that this modifier must
+ not immediately follow the /S modifier because /S+ and /S++ have other
+ meanings.
+
+ The /= modifier requests that the values of all potential captured
+ parentheses be output after a match. By default, only those up to the
+ highest one actually used in the match are output (corresponding to the
+ return code from pcre[16]_exec()). Values in the offsets vector corre-
+ sponding to higher numbers should be set to -1, and these are output as
+ "". This modifier gives a way of checking that this is happen-
+ ing.
The /B modifier is a debugging feature. It requests that pcretest out-
- put a representation of the compiled byte code after compilation. Nor-
- mally this information contains length and offset values; however, if
- /Z is also present, this data is replaced by spaces. This is a special
- feature for use in the automatic test scripts; it ensures that the same
+ put a representation of the compiled code after compilation. Normally
+ this information contains length and offset values; however, if /Z is
+ also present, this data is replaced by spaces. This is a special fea-
+ ture for use in the automatic test scripts; it ensures that the same
output is generated for different internal link sizes.
The /D modifier is a PCRE debugging feature, and is equivalent to /BI,
that is, both the /B and the /I modifiers.
- The /F modifier causes pcretest to flip the byte order of the fields in
- the compiled pattern that contain 2-byte and 4-byte numbers. This
- facility is for testing the feature in PCRE that allows it to execute
- patterns that were compiled on a host with a different endianness. This
- feature is not available when the POSIX interface to PCRE is being
- used, that is, when the /P pattern modifier is specified. See also the
- section about saving and reloading compiled patterns below.
+ The /F modifier causes pcretest to flip the byte order of the 2-byte
+ and 4-byte fields in the compiled pattern. This facility is for testing
+ the feature in PCRE that allows it to execute patterns that were com-
+ piled on a host with a different endianness. This feature is not avail-
+ able when the POSIX interface to PCRE is being used, that is, when the
+ /P pattern modifier is specified. See also the section about saving and
+ reloading compiled patterns below.
The /I modifier requests that pcretest output information about the
compiled pattern (whether it is anchored, has a fixed first character,
- and so on). It does this by calling pcre_fullinfo() after compiling a
- pattern. If the pattern is studied, the results of that are also out-
+ and so on). It does this by calling pcre[16]_fullinfo() after compiling
+ a pattern. If the pattern is studied, the results of that are also out-
put.
The /K modifier requests pcretest to show names from backtracking con-
- trol verbs that are returned from calls to pcre_exec(). It causes
- pcretest to create a pcre_extra block if one has not already been cre-
- ated by a call to pcre_study(), and to set the PCRE_EXTRA_MARK flag and
- the mark field within it, every time that pcre_exec() is called. If the
- variable that the mark field points to is non-NULL for a match, non-
- match, or partial match, pcretest prints the string to which it points.
- For a match, this is shown on a line by itself, tagged with "MK:". For
- a non-match it is added to the message.
+ trol verbs that are returned from calls to pcre[16]_exec(). It causes
+ pcretest to create a pcre[16]_extra block if one has not already been
+ created by a call to pcre[16]_study(), and to set the PCRE_EXTRA_MARK
+ flag and the mark field within it, every time that pcre[16]_exec() is
+ called. If the variable that the mark field points to is non-NULL for a
+ match, non-match, or partial match, pcretest prints the string to which
+ it points. For a match, this is shown on a line by itself, tagged with
+ "MK:". For a non-match it is added to the message.
The /L modifier must be followed directly by the name of a locale, for
example,
@@ -261,22 +361,57 @@
/pattern/Lfr_FR
For this reason, it must be the last modifier. The given locale is set,
- pcre_maketables() is called to build a set of character tables for the
- locale, and this is then passed to pcre_compile() when compiling the
- regular expression. Without an /L (or /T) modifier, NULL is passed as
- the tables pointer; that is, /L applies only to the expression on which
- it appears.
-
- The /M modifier causes the size of memory block used to hold the com-
- piled pattern to be output.
-
- The /S modifier causes pcre_study() to be called after the expression
- has been compiled, and the results used when the expression is matched.
+ pcre[16]_maketables() is called to build a set of character tables for
+ the locale, and this is then passed to pcre[16]_compile() when compil-
+ ing the regular expression. Without an /L (or /T) modifier, NULL is
+ passed as the tables pointer; that is, /L applies only to the expres-
+ sion on which it appears.
+
+ The /M modifier causes the size in bytes of the memory block used to
+ hold the compiled pattern to be output. This does not include the size
+ of the pcre[16] block; it is just the actual compiled data. If the pat-
+ tern is successfully studied with the PCRE_STUDY_JIT_COMPILE option,
+ the size of the JIT compiled code is also output.
+
+ If the /S modifier appears once, it causes pcre[16]_study() to be
+ called after the expression has been compiled, and the results used
+ when the expression is matched. If /S appears twice, it suppresses
+ studying, even if it was requested externally by the -s command line
+ option. This makes it possible to specify that certain patterns are
+ always studied, and others are never studied, independently of -s. This
+ feature is used in the test files in a few cases where the output is
+ different when the pattern is studied.
+
+ If the /S modifier is immediately followed by a + character, the call
+ to pcre[16]_study() is made with all the JIT study options, requesting
+ just-in-time optimization support if it is available, for both normal
+ and partial matching. If you want to restrict the JIT compiling modes,
+ you can follow /S+ with a digit in the range 1 to 7:
+
+ 1 normal match only
+ 2 soft partial match only
+ 3 normal match and soft partial match
+ 4 hard partial match only
+ 6 soft and hard partial match
+ 7 all three modes (default)
+
+ If /S++ is used instead of /S+ (with or without a following digit), the
+ text "(JIT)" is added to the first output line after a match or no
+ match when JIT-compiled code was actually used.
+
+ Note that there is also an independent /+ modifier; it must not be
+ given immediately after /S or /S+ because this will be misinterpreted.
+
+ If JIT studying is successful, the compiled JIT code will automatically
+ be used when pcre[16]_exec() is run, except when incompatible run-time
+ options are specified. For more details, see the pcrejit documentation.
+ See also the \J escape sequence below for a way of setting the size of
+ the JIT stack.
The /T modifier must be followed by a single digit. It causes a spe-
- cific set of built-in character tables to be passed to pcre_compile().
- It is used in the standard PCRE tests to check behaviour with different
- character tables. The digit specifies the tables as follows:
+ cific set of built-in character tables to be passed to pcre[16]_com-
+ pile(). It is used in the standard PCRE tests to check behaviour with
+ different character tables. The digit specifies the tables as follows:
0 the default ASCII tables, as distributed in
pcre_chartables.c.dist
@@ -288,8 +423,9 @@
Using the POSIX wrapper API
The /P modifier causes pcretest to call PCRE via the POSIX wrapper API
- rather than its native API. When /P is set, the following modifiers set
- options for the regcomp() function:
+ rather than its native API. This supports only the 8-bit library. When
+ /P is set, the following modifiers set options for the regcomp() func-
+ tion:
/i REG_ICASE
/m REG_NEWLINE
@@ -299,41 +435,40 @@
/W REG_UCP ) the POSIX standard
/8 REG_UTF8 )
- The /+ modifier works as described above. All other modifiers are
+ The /+ modifier works as described above. All other modifiers are
ignored.
DATA LINES
- Before each data line is passed to pcre_exec(), leading and trailing
- whitespace is removed, and it is then scanned for \ escapes. Some of
- these are pretty esoteric features, intended for checking out some of
- the more complicated features of PCRE. If you are just testing "ordi-
- nary" regular expressions, you probably don't need any of these. The
- following escapes are recognized:
+ Before each data line is passed to pcre[16]_exec(), leading and trail-
+ ing white space is removed, and it is then scanned for \ escapes. Some
+ of these are pretty esoteric features, intended for checking out some
+ of the more complicated features of PCRE. If you are just testing
+ "ordinary" regular expressions, you probably don't need any of these.
+ The following escapes are recognized:
\a alarm (BEL, \x07)
\b backspace (\x08)
\e escape (\x27)
- \f formfeed (\x0c)
+ \f form feed (\x0c)
\n newline (\x0a)
\qdd set the PCRE_MATCH_LIMIT limit to dd
(any number of digits)
\r carriage return (\x0d)
\t tab (\x09)
\v vertical tab (\x0b)
- \nnn octal character (up to 3 octal digits)
- always a byte unless > 255 in UTF-8 mode
+ \nnn octal character (up to 3 octal digits); always
+ a byte unless > 255 in UTF-8 or 16-bit mode
\xhh hexadecimal byte (up to 2 hex digits)
- \x{hh...} hexadecimal character, any number of digits
- in UTF-8 mode
- \A pass the PCRE_ANCHORED option to pcre_exec()
- or pcre_dfa_exec()
- \B pass the PCRE_NOTBOL option to pcre_exec()
- or pcre_dfa_exec()
- \Cdd call pcre_copy_substring() for substring dd
+ \x{hh...} hexadecimal character (any number of hex digits)
+ \A pass the PCRE_ANCHORED option to pcre[16]_exec()
+ or pcre[16]_dfa_exec()
+ \B pass the PCRE_NOTBOL option to pcre[16]_exec()
+ or pcre[16]_dfa_exec()
+ \Cdd call pcre[16]_copy_substring() for substring dd
after a successful match (number less than 32)
- \Cname call pcre_copy_named_substring() for substring
+ \Cname call pcre[16]_copy_named_substring() for substring
"name" after a successful match (name termin-
ated by next non alphanumeric character)
\C+ show the current captured substrings at callout
@@ -345,55 +480,66 @@
reached for the nth time
\C*n pass the number n (may be negative) as callout
data; this is used as the callout return value
- \D use the pcre_dfa_exec() match function
- \F only shortest match for pcre_dfa_exec()
- \Gdd call pcre_get_substring() for substring dd
+ \D use the pcre[16]_dfa_exec() match function
+ \F only shortest match for pcre[16]_dfa_exec()
+ \Gdd call pcre[16]_get_substring() for substring dd
after a successful match (number less than 32)
- \Gname call pcre_get_named_substring() for substring
+ \Gname call pcre[16]_get_named_substring() for substring
"name" after a successful match (name termin-
ated by next non-alphanumeric character)
- \L call pcre_get_substringlist() after a
+ \Jdd set up a JIT stack of dd kilobytes maximum (any
+ number of digits)
+ \L call pcre[16]_get_substringlist() after a
successful match
\M discover the minimum MATCH_LIMIT and
MATCH_LIMIT_RECURSION settings
- \N pass the PCRE_NOTEMPTY option to pcre_exec()
- or pcre_dfa_exec(); if used twice, pass the
+ \N pass the PCRE_NOTEMPTY option to pcre[16]_exec()
+ or pcre[16]_dfa_exec(); if used twice, pass the
PCRE_NOTEMPTY_ATSTART option
\Odd set the size of the output vector passed to
- pcre_exec() to dd (any number of digits)
- \P pass the PCRE_PARTIAL_SOFT option to pcre_exec()
- or pcre_dfa_exec(); if used twice, pass the
+ pcre[16]_exec() to dd (any number of digits)
+ \P pass the PCRE_PARTIAL_SOFT option to pcre[16]_exec()
+ or pcre[16]_dfa_exec(); if used twice, pass the
PCRE_PARTIAL_HARD option
\Qdd set the PCRE_MATCH_LIMIT_RECURSION limit to dd
(any number of digits)
- \R pass the PCRE_DFA_RESTART option to pcre_dfa_exec()
+ \R pass the PCRE_DFA_RESTART option to pcre[16]_dfa_exec()
\S output details of memory get/free calls during matching
- \Y pass the PCRE_NO_START_OPTIMIZE option to pcre_exec()
- or pcre_dfa_exec()
- \Z pass the PCRE_NOTEOL option to pcre_exec()
- or pcre_dfa_exec()
- \? pass the PCRE_NO_UTF8_CHECK option to
- pcre_exec() or pcre_dfa_exec()
+ \Y pass the PCRE_NO_START_OPTIMIZE option to pcre[16]_exec()
+ or pcre[16]_dfa_exec()
+ \Z pass the PCRE_NOTEOL option to pcre[16]_exec()
+ or pcre[16]_dfa_exec()
+ \? pass the PCRE_NO_UTF[8|16]_CHECK option to
+ pcre[16]_exec() or pcre[16]_dfa_exec()
\>dd start the match at offset dd (optional "-"; then
any number of digits); this sets the startoffset
- argument for pcre_exec() or pcre_dfa_exec()
- \ pass the PCRE_NEWLINE_CR option to pcre_exec()
- or pcre_dfa_exec()
- \ pass the PCRE_NEWLINE_LF option to pcre_exec()
- or pcre_dfa_exec()
- \ pass the PCRE_NEWLINE_CRLF option to pcre_exec()
- or pcre_dfa_exec()
- \ pass the PCRE_NEWLINE_ANYCRLF option to pcre_exec()
- or pcre_dfa_exec()
- \ pass the PCRE_NEWLINE_ANY option to pcre_exec()
- or pcre_dfa_exec()
-
- Note that \xhh always specifies one byte, even in UTF-8 mode; this
- makes it possible to construct invalid UTF-8 sequences for testing pur-
- poses. On the other hand, \x{hh} is interpreted as a UTF-8 character in
- UTF-8 mode, generating more than one byte if the value is greater than
- 127. When not in UTF-8 mode, it generates one byte for values less than
- 256, and causes an error for greater values.
+ argument for pcre[16]_exec() or pcre[16]_dfa_exec()
+ \ pass the PCRE_NEWLINE_CR option to pcre[16]_exec()
+ or pcre[16]_dfa_exec()
+ \ pass the PCRE_NEWLINE_LF option to pcre[16]_exec()
+ or pcre[16]_dfa_exec()
+ \ pass the PCRE_NEWLINE_CRLF option to pcre[16]_exec()
+ or pcre[16]_dfa_exec()
+ \ pass the PCRE_NEWLINE_ANYCRLF option to pcre[16]_exec()
+ or pcre[16]_dfa_exec()
+ \ pass the PCRE_NEWLINE_ANY option to pcre[16]_exec()
+ or pcre[16]_dfa_exec()
+
+ The use of \x{hh...} is not dependent on the use of the /8 modifier on
+ the pattern. It is recognized always. There may be any number of hexa-
+ decimal digits inside the braces; invalid values provoke error mes-
+ sages.
+
+ Note that \xhh specifies one byte rather than one character in UTF-8
+ mode; this makes it possible to construct invalid UTF-8 sequences for
+ testing purposes. On the other hand, \x{hh} is interpreted as a UTF-8
+ character in UTF-8 mode, generating more than one byte if the value is
+ greater than 127. When testing the 8-bit library not in UTF-8 mode,
+ \x{hh} generates one byte for values less than 256, and causes an error
+ for greater values.
+
+ In UTF-16 mode, all 4-digit \x{hhhh} values are accepted. This makes it
+ possible to construct invalid UTF-16 sequences for testing purposes.
The escapes that specify line ending sequences are literal strings,
exactly as shown. No more than one newline setting should be present in
@@ -404,70 +550,75 @@
way of passing an empty line as data, since a real empty line termi-
nates the data input.
- If \M is present, pcretest calls pcre_exec() several times, with dif-
- ferent values in the match_limit and match_limit_recursion fields of
- the pcre_extra data structure, until it finds the minimum numbers for
- each parameter that allow pcre_exec() to complete. The match_limit num-
- ber is a measure of the amount of backtracking that takes place, and
- checking it out can be instructive. For most simple matches, the number
- is quite small, but for patterns with very large numbers of matching
- possibilities, it can become large very quickly with increasing length
- of subject string. The match_limit_recursion number is a measure of how
- much stack (or, if PCRE is compiled with NO_RECURSE, how much heap)
- memory is needed to complete the match attempt.
+ The \J escape provides a way of setting the maximum stack size that is
+ used by the just-in-time optimization code. It is ignored if JIT opti-
+ mization is not being used. Providing a stack that is larger than the
+ default 32K is necessary only for very complicated patterns.
+
+ If \M is present, pcretest calls pcre[16]_exec() several times, with
+ different values in the match_limit and match_limit_recursion fields of
+ the pcre[16]_extra data structure, until it finds the minimum numbers
+ for each parameter that allow pcre[16]_exec() to complete without
+ error. Because this is testing a specific feature of the normal inter-
+ pretive pcre[16]_exec() execution, the use of any JIT optimization that
+ might have been set up by the /S+ qualifier of -s+ option is disabled.
+
+ The match_limit number is a measure of the amount of backtracking that
+ takes place, and checking it out can be instructive. For most simple
+ matches, the number is quite small, but for patterns with very large
+ numbers of matching possibilities, it can become large very quickly
+ with increasing length of subject string. The match_limit_recursion
+ number is a measure of how much stack (or, if PCRE is compiled with
+ NO_RECURSE, how much heap) memory is needed to complete the match
+ attempt.
When \O is used, the value specified may be higher or lower than the
size set by the -O command line option (or defaulted to 45); \O applies
- only to the call of pcre_exec() for the line in which it appears.
+ only to the call of pcre[16]_exec() for the line in which it appears.
If the /P modifier was present on the pattern, causing the POSIX wrap-
per API to be used, the only option-setting sequences that have any
effect are \B, \N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and
REG_NOTEOL, respectively, to be passed to regexec().
- The use of \x{hh...} to represent UTF-8 characters is not dependent on
- the use of the /8 modifier on the pattern. It is recognized always.
- There may be any number of hexadecimal digits inside the braces. The
- result is from one to six bytes, encoded according to the original
- UTF-8 rules of RFC 2279. This allows for values in the range 0 to
- 0x7FFFFFFF. Note that not all of those are valid Unicode code points,
- or indeed valid UTF-8 characters according to the later rules in RFC
- 3629.
-
THE ALTERNATIVE MATCHING FUNCTION
- By default, pcretest uses the standard PCRE matching function,
- pcre_exec() to match each data line. From release 6.0, PCRE supports an
- alternative matching function, pcre_dfa_test(), which operates in a
- different way, and has some restrictions. The differences between the
- two functions are described in the pcrematching documentation.
+ By default, pcretest uses the standard PCRE matching function,
+ pcre[16]_exec() to match each data line. PCRE also supports an alterna-
+ tive matching function, pcre[16]_dfa_test(), which operates in a dif-
+ ferent way, and has some restrictions. The differences between the two
+ functions are described in the pcrematching documentation.
- If a data line contains the \D escape sequence, or if the command line
- contains the -dfa option, the alternative matching function is called.
+ If a data line contains the \D escape sequence, or if the command line
+ contains the -dfa option, the alternative matching function is used.
This function finds all possible matches at a given point. If, however,
- the \F escape sequence is present in the data line, it stops after the
+ the \F escape sequence is present in the data line, it stops after the
first match is found. This is always the shortest possible match.
DEFAULT OUTPUT FROM PCRETEST
- This section describes the output when the normal matching function,
- pcre_exec(), is being used.
+ This section describes the output when the normal matching function,
+ pcre[16]_exec(), is being used.
When a match succeeds, pcretest outputs the list of captured substrings
- that pcre_exec() returns, starting with number 0 for the string that
- matched the whole pattern. Otherwise, it outputs "No match" when the
- return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the par-
- tially matching substring when pcre_exec() returns PCRE_ERROR_PARTIAL.
- (Note that this is the entire substring that was inspected during the
- partial match; it may include characters before the actual match start
- if a lookbehind assertion, \K, \b, or \B was involved.) For any other
- returns, it outputs the PCRE negative error number. Here is an example
- of an interactive pcretest run.
+ that pcre[16]_exec() returns, starting with number 0 for the string
+ that matched the whole pattern. Otherwise, it outputs "No match" when
+ the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the
+ partially matching substring when pcre[16]_exec() returns
+ PCRE_ERROR_PARTIAL. (Note that this is the entire substring that was
+ inspected during the partial match; it may include characters before
+ the actual match start if a lookbehind assertion, \K, \b, or \B was
+ involved.) For any other return, pcretest outputs the PCRE negative
+ error number and a short descriptive phrase. If the error is a failed
+ UTF string check, the offset of the start of the failing character and
+ the reason code are also output, provided that the size of the output
+ vector is at least two. Here is an example of an interactive pcretest
+ run.
$ pcretest
- PCRE version 7.0 30-Nov-2006
+ PCRE version 8.13 2011-04-30
re> /^abc(\d+)/
data> abc123
@@ -476,12 +627,12 @@
data> xyz
No match
- Note that unset capturing substrings that are not followed by one that
- is set are not returned by pcre_exec(), and are not shown by pcretest.
- In the following example, there are two capturing substrings, but when
- the first data line is matched, the second, unset substring is not
- shown. An "internal" unset substring is shown as "", as for the
- second data line.
+ Unset capturing substrings that are not followed by one that is set are
+ not returned by pcre[16]_exec(), and are not shown by pcretest. In the
+ following example, there are two capturing substrings, but when the
+ first data line is matched, the second, unset substring is not shown.
+ An "internal" unset substring is shown as "", as for the second
+ data line.
re> /(a)|(b)/
data> a
@@ -492,19 +643,19 @@
1:
2: b
- If the strings contain any non-printing characters, they are output as
- \0x escapes, or as \x{...} escapes if the /8 modifier was present on
- the pattern. See below for the definition of non-printing characters.
- If the pattern has the /+ modifier, the output for substring 0 is fol-
- lowed by the the rest of the subject string, identified by "0+" like
- this:
+ If the strings contain any non-printing characters, they are output as
+ \xhh escapes if the value is less than 256 and UTF mode is not set.
+ Otherwise they are output as \x{hh...} escapes. See below for the defi-
+ nition of non-printing characters. If the pattern has the /+ modifier,
+ the output for substring 0 is followed by the the rest of the subject
+ string, identified by "0+" like this:
re> /cat/+
data> cataract
0: cat
0+ aract
- If the pattern has the /g or /G modifier, the results of successive
+ If the pattern has the /g or /G modifier, the results of successive
matching attempts are output in sequence, like this:
re> /\Bi(\w\w)/g
@@ -516,27 +667,34 @@
0: ipp
1: pp
- "No match" is output only if the first match attempt fails.
+ "No match" is output only if the first match attempt fails. Here is an
+ example of a failure message (the offset 4 that is specified by \>4 is
+ past the end of the subject string):
+
+ re> /xyz/
+ data> xyz\>4
+ Error -24 (bad offset value)
- If any of the sequences \C, \G, or \L are present in a data line that
- is successfully matched, the substrings extracted by the convenience
+ If any of the sequences \C, \G, or \L are present in a data line that
+ is successfully matched, the substrings extracted by the convenience
functions are output with C, G, or L after the string number instead of
a colon. This is in addition to the normal full list. The string length
- (that is, the return from the extraction function) is given in paren-
+ (that is, the return from the extraction function) is given in paren-
theses after each string for \C and \G.
Note that whereas patterns can be continued over several lines (a plain
">" prompt is used for continuations), data lines may not. However new-
- lines can be included in data by means of the \n escape (or \r, \r\n,
+ lines can be included in data by means of the \n escape (or \r, \r\n,
etc., depending on the newline sequence setting).
OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
- When the alternative matching function, pcre_dfa_exec(), is used (by
- means of the \D escape sequence or the -dfa command line option), the
- output consists of a list of all the matches that start at the first
- point in the subject where there is at least one match. For example:
+ When the alternative matching function, pcre[16]_dfa_exec(), is used
+ (by means of the \D escape sequence or the -dfa command line option),
+ the output consists of a list of all the matches that start at the
+ first point in the subject where there is at least one match. For exam-
+ ple:
re> /(tang|tangerine|tan)/
data> yellow tangerine\D
@@ -592,16 +750,16 @@
tion is called during matching. This works with both matching func-
tions. By default, the called function displays the callout number, the
start and current positions in the text at the callout time, and the
- next pattern item to be tested. For example, the output
+ next pattern item to be tested. For example:
--->pqrabcdef
0 ^ ^ \d
- indicates that callout number 0 occurred for a match attempt starting
- at the fourth character of the subject string, when the pointer was at
- the seventh character of the data, and when the next pattern item was
- \d. Just one circumflex is output if the start and current positions
- are the same.
+ This output indicates that callout number 0 occurred for a match
+ attempt starting at the fourth character of the subject string, when
+ the pointer was at the seventh character of the data, and when the next
+ pattern item was \d. Just one circumflex is output if the start and
+ current positions are the same.
Callouts numbered 255 are assumed to be automatic callouts, inserted as
a result of the /C pattern modifier. In this case, instead of showing
@@ -617,41 +775,62 @@
+10 ^ ^
0: E*
- The callout function in pcretest returns zero (carry on matching) by
- default, but you can use a \C item in a data line (as described above)
- to change this.
+ If a pattern contains (*MARK) items, an additional line is output when-
+ ever a change of latest mark is passed to the callout function. For
+ example:
+
+ re> /a(*MARK:X)bc/C
+ data> abc
+ --->abc
+ +0 ^ a
+ +1 ^^ (*MARK:X)
+ +10 ^^ b
+ Latest Mark: X
+ +11 ^ ^ c
+ +12 ^ ^
+ 0: abc
+
+ The mark changes between matching "a" and "b", but stays the same for
+ the rest of the match, so nothing more is output. If, as a result of
+ backtracking, the mark reverts to being unset, the text "" is
+ output.
+
+ The callout function in pcretest returns zero (carry on matching) by
+ default, but you can use a \C item in a data line (as described above)
+ to change this and other parameters of the callout.
- Inserting callouts can be helpful when using pcretest to check compli-
- cated regular expressions. For further information about callouts, see
+ Inserting callouts can be helpful when using pcretest to check compli-
+ cated regular expressions. For further information about callouts, see
the pcrecallout documentation.
NON-PRINTING CHARACTERS
- When pcretest is outputting text in the compiled version of a pattern,
- bytes other than 32-126 are always treated as non-printing characters
+ When pcretest is outputting text in the compiled version of a pattern,
+ bytes other than 32-126 are always treated as non-printing characters
are are therefore shown as hex escapes.
- When pcretest is outputting text that is a matched part of a subject
- string, it behaves in the same way, unless a different locale has been
- set for the pattern (using the /L modifier). In this case, the
+ When pcretest is outputting text that is a matched part of a subject
+ string, it behaves in the same way, unless a different locale has been
+ set for the pattern (using the /L modifier). In this case, the
isprint() function to distinguish printing and non-printing characters.
SAVING AND RELOADING COMPILED PATTERNS
- The facilities described in this section are not available when the
- POSIX inteface to PCRE is being used, that is, when the /P pattern mod-
- ifier is specified.
+ The facilities described in this section are not available when the
+ POSIX interface to PCRE is being used, that is, when the /P pattern
+ modifier is specified.
When the POSIX interface is not in use, you can cause pcretest to write
- a compiled pattern to a file, by following the modifiers with > and a
+ a compiled pattern to a file, by following the modifiers with > and a
file name. For example:
/pattern/im >/some/file
- See the pcreprecompile documentation for a discussion about saving and
- re-using compiled patterns.
+ See the pcreprecompile documentation for a discussion about saving and
+ re-using compiled patterns. Note that if the pattern was successfully
+ studied with JIT optimization, the JIT data cannot be saved.
The data that is written is binary. The first eight bytes are the
length of the compiled pattern data followed by the length of the
@@ -659,45 +838,56 @@
(most significant byte first). If there is no study data (either the
pattern was not studied, or studying did not return any data), the sec-
ond length is zero. The lengths are followed by an exact copy of the
- compiled pattern. If there is additional study data, this follows imme-
- diately after the compiled pattern. After writing the file, pcretest
- expects to read a new pattern.
-
- A saved pattern can be reloaded into pcretest by specifing < and a file
- name instead of a pattern. The name of the file must not contain a <
- character, as otherwise pcretest will interpret the line as a pattern
+ compiled pattern. If there is additional study data, this (excluding
+ any JIT data) follows immediately after the compiled pattern. After
+ writing the file, pcretest expects to read a new pattern.
+
+ A saved pattern can be reloaded into pcretest by specifying < and a
+ file name instead of a pattern. The name of the file must not contain a
+ < character, as otherwise pcretest will interpret the line as a pattern
delimited by < characters. For example:
re>
+.\"
+\fBpcre16_compile()\fP
+.\"
+with the PCRE_UTF16 option flag, or the pattern must start with the sequence
+(*UTF16). When either of these is the case, both the pattern and any subject
+strings that are matched against it are treated as UTF-16 strings instead of
+strings of 16-bit characters.
+.
+.
+.SH "UTF SUPPORT OVERHEAD"
+.rs
+.sp
+If you compile PCRE with UTF support, but do not use it at run time, the
+library will be a bit bigger, but the additional run time overhead is limited
+to testing the PCRE_UTF8/16 flag occasionally, so should not be very big.
+.
+.
+.SH "UNICODE PROPERTY SUPPORT"
+.rs
+.sp
+If PCRE is built with Unicode character property support (which implies UTF
+support), the escape sequences \ep{..}, \eP{..}, and \eX can be used.
+The available properties that can be tested are limited to the general
+category properties such as Lu for an upper case letter or Nd for a decimal
+number, the Unicode script names such as Arabic or Han, and the derived
+properties Any and L&. A full list is given in the
+.\" HREF
+\fBpcrepattern\fP
+.\"
+documentation. Only the short names for properties are supported. For example,
+\ep{L} matches a letter. Its Perl synonym, \ep{Letter}, is not supported.
+Furthermore, in Perl, many properties may optionally be prefixed by "Is", for
+compatibility with Perl 5.6. PCRE does not support this.
+.
+.
+.\" HTML
+.SS "Validity of UTF-8 strings"
+.rs
+.sp
+When you set the PCRE_UTF8 flag, the byte strings passed as patterns and
+subjects are (by default) checked for validity on entry to the relevant
+functions. The entire string is checked before any other processing takes
+place. From release 7.3 of PCRE, the check is according the rules of RFC 3629,
+which are themselves derived from the Unicode specification. Earlier releases
+of PCRE followed the rules of RFC 2279, which allows the full range of 31-bit
+values (0 to 0x7FFFFFFF). The current check allows only values in the range U+0
+to U+10FFFF, excluding U+D800 to U+DFFF.
+.P
+The excluded code points are the "Surrogate Area" of Unicode. They are reserved
+for use by UTF-16, where they are used in pairs to encode codepoints with
+values greater than 0xFFFF. The code points that are encoded by UTF-16 pairs
+are available independently in the UTF-8 encoding. (In other words, the whole
+surrogate thing is a fudge for UTF-16 which unfortunately messes up UTF-8.)
+.P
+If an invalid UTF-8 string is passed to PCRE, an error return is given. At
+compile time, the only additional information is the offset to the first byte
+of the failing character. The run-time functions \fBpcre_exec()\fP and
+\fBpcre_dfa_exec()\fP also pass back this information, as well as a more
+detailed reason code if the caller has provided memory in which to do this.
+.P
+In some situations, you may already know that your strings are valid, and
+therefore want to skip these checks in order to improve performance, for
+example in the case of a long subject string that is being scanned repeatedly
+with different patterns. If you set the PCRE_NO_UTF8_CHECK flag at compile time
+or at run time, PCRE assumes that the pattern or subject it is given
+(respectively) contains only valid UTF-8 codes. In this case, it does not
+diagnose an invalid UTF-8 string.
+.P
+If you pass an invalid UTF-8 string when PCRE_NO_UTF8_CHECK is set, what
+happens depends on why the string is invalid. If the string conforms to the
+"old" definition of UTF-8 (RFC 2279), it is processed as a string of characters
+in the range 0 to 0x7FFFFFFF by \fBpcre_dfa_exec()\fP and the interpreted
+version of \fBpcre_exec()\fP. In other words, apart from the initial validity
+test, these functions (when in UTF-8 mode) handle strings according to the more
+liberal rules of RFC 2279. However, the just-in-time (JIT) optimization for
+\fBpcre_exec()\fP supports only RFC 3629. If you are using JIT optimization, or
+if the string does not even conform to RFC 2279, the result is undefined. Your
+program may crash.
+.P
+If you want to process strings of values in the full range 0 to 0x7FFFFFFF,
+encoded in a UTF-8-like manner as per the old RFC, you can set
+PCRE_NO_UTF8_CHECK to bypass the more restrictive test. However, in this
+situation, you will have to apply your own validity check, and avoid the use of
+JIT optimization.
+.
+.
+.\" HTML
+.SS "Validity of UTF-16 strings"
+.rs
+.sp
+When you set the PCRE_UTF16 flag, the strings of 16-bit data units that are
+passed as patterns and subjects are (by default) checked for validity on entry
+to the relevant functions. Values other than those in the surrogate range
+U+D800 to U+DFFF are independent code points. Values in the surrogate range
+must be used in pairs in the correct manner.
+.P
+If an invalid UTF-16 string is passed to PCRE, an error return is given. At
+compile time, the only additional information is the offset to the first data
+unit of the failing character. The run-time functions \fBpcre16_exec()\fP and
+\fBpcre16_dfa_exec()\fP also pass back this information, as well as a more
+detailed reason code if the caller has provided memory in which to do this.
+.P
+In some situations, you may already know that your strings are valid, and
+therefore want to skip these checks in order to improve performance. If you set
+the PCRE_NO_UTF16_CHECK flag at compile time or at run time, PCRE assumes that
+the pattern or subject it is given (respectively) contains only valid UTF-16
+sequences. In this case, it does not diagnose an invalid UTF-16 string.
+.
+.
+.SS "General comments about UTF modes"
+.rs
+.sp
+1. Codepoints less than 256 can be specified by either braced or unbraced
+hexadecimal escape sequences (for example, \ex{b3} or \exb3). Larger values
+have to use braced sequences.
+.P
+2. Octal numbers up to \e777 are recognized, and in UTF-8 mode, they match
+two-byte characters for values greater than \e177.
+.P
+3. Repeat quantifiers apply to complete UTF characters, not to individual
+data units, for example: \ex{100}{3}.
+.P
+4. The dot metacharacter matches one UTF character instead of a single data
+unit.
+.P
+5. The escape sequence \eC can be used to match a single byte in UTF-8 mode, or
+a single 16-bit data unit in UTF-16 mode, but its use can lead to some strange
+effects because it breaks up multi-unit characters (see the description of \eC
+in the
+.\" HREF
+\fBpcrepattern\fP
+.\"
+documentation). The use of \eC is not supported in the alternative matching
+function \fBpcre[16]_dfa_exec()\fP, nor is it supported in UTF mode by the JIT
+optimization of \fBpcre[16]_exec()\fP. If JIT optimization is requested for a
+UTF pattern that contains \eC, it will not succeed, and so the matching will
+be carried out by the normal interpretive function.
+.P
+6. The character escapes \eb, \eB, \ed, \eD, \es, \eS, \ew, and \eW correctly
+test characters of any code value, but, by default, the characters that PCRE
+recognizes as digits, spaces, or word characters remain the same set as in
+non-UTF mode, all with values less than 256. This remains true even when PCRE
+is built to include Unicode property support, because to do otherwise would
+slow down PCRE in many common cases. Note in particular that this applies to
+\eb and \eB, because they are defined in terms of \ew and \eW. If you really
+want to test for a wider sense of, say, "digit", you can use explicit Unicode
+property tests such as \ep{Nd}. Alternatively, if you set the PCRE_UCP option,
+the way that the character escapes work is changed so that Unicode properties
+are used to determine which characters match. There are more details in the
+section on
+.\" HTML
+.\"
+generic character types
+.\"
+in the
+.\" HREF
+\fBpcrepattern\fP
+.\"
+documentation.
+.P
+7. Similarly, characters that match the POSIX named character classes are all
+low-valued characters, unless the PCRE_UCP option is set.
+.P
+8. However, the horizontal and vertical white space matching escapes (\eh, \eH,
+\ev, and \eV) do match all the appropriate Unicode characters, whether or not
+PCRE_UCP is set.
+.P
+9. Case-insensitive matching applies only to characters whose values are less
+than 128, unless PCRE is built with Unicode property support. Even when Unicode
+property support is available, PCRE still uses its own character tables when
+checking the case of low-valued characters, so as not to degrade performance.
+The Unicode property information is used only for characters with higher
+values. Furthermore, PCRE supports case-insensitive matching only when there is
+a one-to-one mapping between a letter's cases. There are a small number of
+many-to-one mappings in Unicode; these are not supported by PCRE.
+.
+.
+.SH AUTHOR
+.rs
+.sp
+.nf
+Philip Hazel
+University Computing Service
+Cambridge CB2 3QH, England.
+.fi
+.
+.
+.SH REVISION
+.rs
+.sp
+.nf
+Last updated: 14 April 2012
+Copyright (c) 1997-2012 University of Cambridge.
+.fi
diff -Nru pcre3-8.12/doc/perltest.txt pcre3-8.31/doc/perltest.txt
--- pcre3-8.12/doc/perltest.txt 2009-10-05 10:40:30.000000000 +0000
+++ pcre3-8.31/doc/perltest.txt 2012-01-21 16:00:28.000000000 +0000
@@ -3,30 +3,40 @@
The perltest.pl script tests Perl's regular expressions; it has the same
specification as pcretest, and so can be given identical input, except that
-input patterns can be followed only by Perl's lower case modifiers and /+ (as
-used by pcretest), which is recognized and handled by the program.
+input patterns can be followed only by Perl's lower case modifiers and certain
+other pcretest modifiers that are either handled or ignored:
-The data lines are processed as Perl double-quoted strings, so if they contain
-" $ or @ characters, these have to be escaped. For this reason, all such
-characters in testinput1, testinput4, testinput6, and testinput11 are escaped
-so that they can be used for perltest as well as for pcretest. The special
-upper case pattern modifiers such as /A that pcretest recognizes, and its
-special data line escapes, are not used in these files. The output should be
-identical, apart from the initial identifying banner.
+ /+ recognized and handled by perltest
+ /++ the second + is ignored
+ /8 recognized and handled by perltest
+ /J ignored
+ /K ignored
+ /W ignored
+ /S ignored
+ /SS ignored
+ /Y ignored
+
+The pcretest \Y escape in data lines is removed before matching. The data lines
+are processed as Perl double-quoted strings, so if they contain " $ or @
+characters, these have to be escaped. For this reason, all such characters in
+the Perl-compatible testinput1 file are escaped so that they can be used for
+perltest as well as for pcretest. The special upper case pattern modifiers such
+as /A that pcretest recognizes, and its special data line escapes, are not used
+in the Perl-compatible test file. The output should be identical, apart from
+the initial identifying banner.
The perltest.pl script can also test UTF-8 features. It recognizes the special
modifier /8 that pcretest uses to invoke UTF-8 functionality. The testinput4
and testinput6 files can be fed to perltest to run compatible UTF-8 tests.
-However, it is necessary to add "use utf8;" to the script to make this work
-correctly.
-
-The testinput11 file contains tests that use features of Perl 5.10, so does not
-work with Perl 5.8.
+However, it is necessary to add "use utf8; require Encode" to the script to
+make this work correctly. I have not managed to find a way to handle this
+automatically.
The other testinput files are not suitable for feeding to perltest.pl, since
they make use of the special upper case modifiers and escapes that pcretest
-uses to test some features of PCRE. Some of these files also contains malformed
-regular expressions, in order to check that PCRE diagnoses them correctly.
+uses to test certain features of PCRE. Some of these files also contain
+malformed regular expressions, in order to check that PCRE diagnoses them
+correctly.
Philip Hazel
-October 2009
+January 2012
diff -Nru pcre3-8.12/libpcre.pc.in pcre3-8.31/libpcre.pc.in
--- pcre3-8.12/libpcre.pc.in 2009-09-01 16:20:54.000000000 +0000
+++ pcre3-8.31/libpcre.pc.in 2011-12-28 16:57:58.000000000 +0000
@@ -6,7 +6,7 @@
includedir=@includedir@
Name: libpcre
-Description: PCRE - Perl compatible regular expressions C library
+Description: PCRE - Perl compatible regular expressions C library with 8 bit character support
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lpcre
Cflags: -I${includedir} @PCRE_STATIC_CFLAG@
diff -Nru pcre3-8.12/libpcre16.pc.in pcre3-8.31/libpcre16.pc.in
--- pcre3-8.12/libpcre16.pc.in 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/libpcre16.pc.in 2012-01-01 14:36:09.000000000 +0000
@@ -0,0 +1,12 @@
+# Package Information for pkg-config
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libpcre16
+Description: PCRE - Perl compatible regular expressions C library with 16 bit character support
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lpcre16
+Cflags: -I${includedir} @PCRE_STATIC_CFLAG@
diff -Nru pcre3-8.12/ltmain.sh pcre3-8.31/ltmain.sh
--- pcre3-8.12/ltmain.sh 2011-01-15 11:27:55.000000000 +0000
+++ pcre3-8.31/ltmain.sh 2012-07-06 09:01:59.000000000 +0000
@@ -1,6 +1,5 @@
-# Generated from ltmain.m4sh.
-# libtool (GNU libtool) 2.2.10
+# libtool (GNU libtool) 2.4
# Written by Gordon Matzigkeit , 1996
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
@@ -70,17 +69,19 @@
# compiler: $LTCC
# compiler flags: $LTCFLAGS
# linker: $LD (gnu? $with_gnu_ld)
-# $progname: (GNU libtool) 2.2.10
+# $progname: (GNU libtool) 2.4
# automake: $automake_version
# autoconf: $autoconf_version
#
# Report bugs to .
+# GNU libtool home page: .
+# General help using GNU software: .
PROGRAM=libtool
PACKAGE=libtool
-VERSION=2.2.10
+VERSION=2.4
TIMESTAMP=""
-package_revision=1.3175
+package_revision=1.3293
# Be Bourne compatible
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
@@ -163,6 +164,27 @@
dirname="s,/[^/]*$,,"
basename="s,^.*/,,"
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
# func_dirname_and_basename file append nondir_replacement
# perform func_basename and func_dirname in a single function
# call:
@@ -177,17 +199,31 @@
# those functions but instead duplicate the functionality here.
func_dirname_and_basename ()
{
- # Extract subdirectory from the argument.
- func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
- if test "X$func_dirname_result" = "X${1}"; then
- func_dirname_result="${3}"
- else
- func_dirname_result="$func_dirname_result${2}"
- fi
- func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
-}
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+} # func_stripname may be replaced by extended shell implementation
-# Generated shell functions inserted here.
# These SED scripts presuppose an absolute path with a trailing slash.
pathcar='s,^/\([^/]*\).*$,\1,'
@@ -370,6 +406,15 @@
# Same as above, but do not quote variable references.
double_quote_subst='s/\(["`\\]\)/\\\1/g'
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
# Re-`\' parameter expansions in output of double_quote_subst that were
# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
# in input to double_quote_subst, that '$' was protected from expansion.
@@ -398,7 +443,7 @@
# name if it has been set yet.
func_echo ()
{
- $ECHO "$progname${mode+: }$mode: $*"
+ $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
}
# func_verbose arg...
@@ -424,14 +469,14 @@
# Echo program name prefixed message to standard error.
func_error ()
{
- $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
+ $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
}
# func_warning arg...
# Echo program name prefixed warning message to standard error.
func_warning ()
{
- $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
+ $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
# bash bug again:
:
@@ -650,11 +695,30 @@
fi
}
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
# func_version
# Echo version message to standard output and exit.
func_version ()
{
+ $opt_debug
+
$SED -n '/(C)/!b go
:more
/\./!{
@@ -676,6 +740,8 @@
# Echo short help message to standard output and exit.
func_usage ()
{
+ $opt_debug
+
$SED -n '/^# Usage:/,/^# *.*--help/ {
s/^# //
s/^# *$//
@@ -692,7 +758,10 @@
# unless 'noexit' is passed as argument.
func_help ()
{
+ $opt_debug
+
$SED -n '/^# Usage:/,/# Report bugs to/ {
+ :print
s/^# //
s/^# *$//
s*\$progname*'$progname'*
@@ -705,7 +774,11 @@
s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
p
- }' < "$progpath"
+ d
+ }
+ /^# .* home page:/b print
+ /^# General help using/b print
+ ' < "$progpath"
ret=$?
if test -z "$1"; then
exit $ret
@@ -717,12 +790,39 @@
# exit_cmd.
func_missing_arg ()
{
+ $opt_debug
+
func_error "missing argument for $1."
exit_cmd=exit
}
-exit_cmd=:
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+ my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+ my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+ func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+ func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+ my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+ my_sed_long_arg='1s/^--[^=]*=//'
+
+ func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+ func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
@@ -732,25 +832,64 @@
magic_exe="%%%MAGIC EXE variable%%%"
# Global variables.
-# $mode is unset
nonopt=
-execute_dlfiles=
preserve_args=
lo2o="s/\\.lo\$/.${objext}/"
o2lo="s/\\.${objext}\$/.lo/"
extracted_archives=
extracted_serial=0
-opt_dry_run=false
-opt_duplicate_deps=false
-opt_silent=false
-opt_debug=:
-
# If this variable is set in any of the actions, the command in it
# will be execed at the end. This prevents here-documents from being
# left over by shells.
exec_cmd=
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+ func_quote_for_eval "${2}"
+ eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
# func_fatal_configuration arg...
# Echo program name prefixed message to standard error, followed by
# a configuration failure hint, and exit.
@@ -840,129 +979,204 @@
esac
}
-# Parse options once, thoroughly. This comes as soon as possible in
-# the script to make things like `libtool --version' happen quickly.
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
- # Shorthand for --mode=foo, only valid as the first argument
- case $1 in
- clean|clea|cle|cl)
- shift; set dummy --mode clean ${1+"$@"}; shift
- ;;
- compile|compil|compi|comp|com|co|c)
- shift; set dummy --mode compile ${1+"$@"}; shift
- ;;
- execute|execut|execu|exec|exe|ex|e)
- shift; set dummy --mode execute ${1+"$@"}; shift
- ;;
- finish|finis|fini|fin|fi|f)
- shift; set dummy --mode finish ${1+"$@"}; shift
- ;;
- install|instal|insta|inst|ins|in|i)
- shift; set dummy --mode install ${1+"$@"}; shift
- ;;
- link|lin|li|l)
- shift; set dummy --mode link ${1+"$@"}; shift
- ;;
- uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
- shift; set dummy --mode uninstall ${1+"$@"}; shift
- ;;
- esac
- # Parse non-mode specific arguments:
- while test "$#" -gt 0; do
+# Parse options once, thoroughly. This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+ # this just eases exit handling
+ while test $# -gt 0; do
opt="$1"
shift
-
case $opt in
- --config) func_config ;;
-
- --debug) preserve_args="$preserve_args $opt"
+ --debug|-x) opt_debug='set -x'
func_echo "enabling shell trace mode"
- opt_debug='set -x'
$opt_debug
;;
-
- -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break
- execute_dlfiles="$execute_dlfiles $1"
- shift
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
;;
-
- --dry-run | -n) opt_dry_run=: ;;
- --features) func_features ;;
- --finish) mode="finish" ;;
-
- --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break
- case $1 in
- # Valid mode arguments:
- clean) ;;
- compile) ;;
- execute) ;;
- finish) ;;
- install) ;;
- link) ;;
- relink) ;;
- uninstall) ;;
-
- # Catch anything else as an error
- *) func_error "invalid argument for $opt"
- exit_cmd=exit
- break
- ;;
- esac
-
- mode="$1"
+ --config)
+ opt_config=:
+func_config
+ ;;
+ --dlopen|-dlopen)
+ optarg="$1"
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
shift
;;
-
--preserve-dup-deps)
- opt_duplicate_deps=: ;;
-
- --quiet|--silent) preserve_args="$preserve_args $opt"
- opt_silent=:
- opt_verbose=false
+ opt_preserve_dup_deps=:
;;
-
- --no-quiet|--no-silent)
- preserve_args="$preserve_args $opt"
- opt_silent=false
+ --features)
+ opt_features=:
+func_features
;;
-
- --verbose| -v) preserve_args="$preserve_args $opt"
+ --finish)
+ opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ --help)
+ opt_help=:
+ ;;
+ --help-all)
+ opt_help_all=:
+opt_help=': help-all'
+ ;;
+ --mode)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_mode="$optarg"
+case $optarg in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+esac
+ shift
+ ;;
+ --no-silent|--no-quiet)
opt_silent=false
- opt_verbose=:
+func_append preserve_args " $opt"
;;
-
- --no-verbose) preserve_args="$preserve_args $opt"
+ --no-verbose)
opt_verbose=false
+func_append preserve_args " $opt"
;;
-
- --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break
- preserve_args="$preserve_args $opt $1"
- func_enable_tag "$1" # tagname is set here
+ --silent|--quiet)
+ opt_silent=:
+func_append preserve_args " $opt"
+ opt_verbose=false
+ ;;
+ --verbose|-v)
+ opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+ ;;
+ --tag)
+ test $# = 0 && func_missing_arg $opt && break
+ optarg="$1"
+ opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
shift
;;
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+ --version) func_version ;;
+
# Separate optargs to long options:
- -dlopen=*|--mode=*|--tag=*)
- func_opt_split "$opt"
- set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
+ --*=*)
+ func_split_long_opt "$opt"
+ set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
shift
;;
- -\?|-h) func_usage ;;
- --help) opt_help=: ;;
- --help-all) opt_help=': help-all' ;;
- --version) func_version ;;
-
- -*) func_fatal_help "unrecognized option \`$opt'" ;;
-
- *) nonopt="$opt"
- break
+ # Separate non-argument short options:
+ -\?*|-h*|-n*|-v*)
+ func_split_short_opt "$opt"
+ set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+ *) set dummy "$opt" ${1+"$@"}; shift; break ;;
esac
done
+ # Validate options:
+
+ # save first non-option argument
+ if test "$#" -gt 0; then
+ nonopt="$opt"
+ shift
+ fi
+
+ # preserve --debug
+ test "$opt_debug" = : || func_append preserve_args " --debug"
case $host in
*cygwin* | *mingw* | *pw32* | *cegcc*)
@@ -970,82 +1184,44 @@
opt_duplicate_compiler_generated_deps=:
;;
*)
- opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
;;
esac
- # Having warned about all mis-specified options, bail out if
- # anything was wrong.
- $exit_cmd $EXIT_FAILURE
-}
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
-# func_check_version_match
-# Ensure that we are using m4 macros, and libtool script from the same
-# release of libtool.
-func_check_version_match ()
-{
- if test "$package_revision" != "$macro_revision"; then
- if test "$VERSION" != "$macro_version"; then
- if test -z "$macro_version"; then
- cat >&2 <<_LT_EOF
-$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
-$progname: definition of this LT_INIT comes from an older release.
-$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
-$progname: and run autoconf again.
-_LT_EOF
- else
- cat >&2 <<_LT_EOF
-$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
-$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
-$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
-$progname: and run autoconf again.
-_LT_EOF
- fi
- else
- cat >&2 <<_LT_EOF
-$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
-$progname: but the definition of this LT_INIT comes from revision $macro_revision.
-$progname: You should recreate aclocal.m4 with macros from revision $package_revision
-$progname: of $PACKAGE $VERSION and run autoconf again.
-_LT_EOF
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
fi
- exit $EXIT_MISMATCH
- fi
-}
-
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
-## ----------- ##
-## Main. ##
-## ----------- ##
-
-$opt_help || {
- # Sanity checks first:
- func_check_version_match
-
- if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
- func_fatal_configuration "not configured to build any kind of library"
- fi
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
- test -z "$mode" && func_fatal_error "error: you must specify a MODE."
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$opt_mode' for more information."
+ }
- # Darwin sucks
- eval std_shrext=\"$shrext_cmds\"
+ # Bail if the options were screwed
+ $exit_cmd $EXIT_FAILURE
+}
- # Only execute mode is allowed to have -dlopen flags.
- if test -n "$execute_dlfiles" && test "$mode" != execute; then
- func_error "unrecognized option \`-dlopen'"
- $ECHO "$help" 1>&2
- exit $EXIT_FAILURE
- fi
- # Change the help message to a mode-specific one.
- generic_help="$help"
- help="Try \`$progname --help --mode=$mode' for more information."
-}
+## ----------- ##
+## Main. ##
+## ----------- ##
# func_lalib_p file
# True iff FILE is a libtool `.la' library or `.lo' object file.
@@ -1110,12 +1286,9 @@
# temporary ltwrapper_script.
func_ltwrapper_scriptname ()
{
- func_ltwrapper_scriptname_result=""
- if func_ltwrapper_executable_p "$1"; then
- func_dirname_and_basename "$1" "" "."
- func_stripname '' '.exe' "$func_basename_result"
- func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
- fi
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
}
# func_ltwrapper_p file
@@ -1161,6 +1334,37 @@
}
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case "$lt_sysroot:$1" in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result="=$func_stripname_result"
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
# func_infer_tag arg
# Infer tagged configuration to use if any are available and
# if one wasn't chosen via the "--tag" command line option.
@@ -1173,8 +1377,7 @@
if test -n "$available_tags" && test -z "$tagname"; then
CC_quoted=
for arg in $CC; do
- func_quote_for_eval "$arg"
- CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ func_append_quoted CC_quoted "$arg"
done
CC_expanded=`func_echo_all $CC`
CC_quoted_expanded=`func_echo_all $CC_quoted`
@@ -1193,8 +1396,7 @@
CC_quoted=
for arg in $CC; do
# Double-quote args containing other shell metacharacters.
- func_quote_for_eval "$arg"
- CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ func_append_quoted CC_quoted "$arg"
done
CC_expanded=`func_echo_all $CC`
CC_quoted_expanded=`func_echo_all $CC_quoted`
@@ -1226,42 +1428,522 @@
-# func_write_libtool_object output_name pic_name nonpic_name
-# Create a libtool object file (analogous to a ".la" file),
-# but don't create it if we're doing a dry run.
-func_write_libtool_object ()
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
+ else
+ write_lobj=none
+ fi
+
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T </dev/null`
+ if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $opt_debug
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=""
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $opt_debug
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $opt_debug
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $opt_debug
+ if test -z "$2" && test -n "$1" ; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " \`$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result="$1"
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $opt_debug
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " \`$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result="$3"
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $opt_debug
+ case $4 in
+ $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $opt_debug
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $opt_debug
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $opt_debug
+ func_to_host_file_result="$1"
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result="$func_cygpath_result"
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $opt_debug
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd="func_convert_path_${func_stripname_result}"
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $opt_debug
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
{
- write_libobj=${1}
- if test "$build_libtool_libs" = yes; then
- write_lobj=\'${2}\'
- else
- write_lobj=none
- fi
+ func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
- if test "$build_old_libs" = yes; then
- write_oldobj=\'${3}\'
- else
- write_oldobj=none
- fi
- $opt_dry_run || {
- cat >${write_libobj}T < "$lockfile"
fi
$opt_dry_run || $RM $removelist
- removelist="$removelist $lockfile"
+ func_append removelist " $lockfile"
trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
- if test -n "$fix_srcfile_path"; then
- eval srcfile=\"$fix_srcfile_path\"
- fi
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
func_quote_for_eval "$srcfile"
qsrcfile=$func_quote_for_eval_result
@@ -1515,7 +2194,7 @@
if test -z "$output_obj"; then
# Place PIC objects in $objdir
- command="$command -o $lobj"
+ func_append command " -o $lobj"
fi
func_show_eval_locale "$command" \
@@ -1562,11 +2241,11 @@
command="$base_compile $qsrcfile $pic_flag"
fi
if test "$compiler_c_o" = yes; then
- command="$command -o $obj"
+ func_append command " -o $obj"
fi
# Suppress compiler output if we already did a PIC compilation.
- command="$command$suppress_output"
+ func_append command "$suppress_output"
func_show_eval_locale "$command" \
'$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
@@ -1611,13 +2290,13 @@
}
$opt_help || {
- test "$mode" = compile && func_mode_compile ${1+"$@"}
+ test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
}
func_mode_help ()
{
# We need to display help for each of the modes.
- case $mode in
+ case $opt_mode in
"")
# Generic help is extracted from the usage comments
# at the start of this file.
@@ -1793,7 +2472,7 @@
;;
*)
- func_fatal_help "invalid operation mode \`$mode'"
+ func_fatal_help "invalid operation mode \`$opt_mode'"
;;
esac
@@ -1808,13 +2487,13 @@
else
{
func_help noexit
- for mode in compile link execute install finish uninstall clean; do
+ for opt_mode in compile link execute install finish uninstall clean; do
func_mode_help
done
} | sed -n '1p; 2,$s/^Usage:/ or: /p'
{
func_help noexit
- for mode in compile link execute install finish uninstall clean; do
+ for opt_mode in compile link execute install finish uninstall clean; do
echo
func_mode_help
done
@@ -1843,13 +2522,16 @@
func_fatal_help "you must specify a COMMAND"
# Handle -dlopen flags immediately.
- for file in $execute_dlfiles; do
+ for file in $opt_dlopen; do
test -f "$file" \
|| func_fatal_help "\`$file' is not a file"
dir=
case $file in
*.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
# Check to see that this really is a libtool archive.
func_lalib_unsafe_p "$file" \
|| func_fatal_help "\`$lib' is not a valid libtool archive"
@@ -1871,7 +2553,7 @@
dir="$func_dirname_result"
if test -f "$dir/$objdir/$dlname"; then
- dir="$dir/$objdir"
+ func_append dir "/$objdir"
else
if test ! -f "$dir/$dlname"; then
func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
@@ -1928,8 +2610,7 @@
;;
esac
# Quote arguments (to preserve shell metacharacters).
- func_quote_for_eval "$file"
- args="$args $func_quote_for_eval_result"
+ func_append_quoted args "$file"
done
if test "X$opt_dry_run" = Xfalse; then
@@ -1961,22 +2642,59 @@
fi
}
-test "$mode" = execute && func_mode_execute ${1+"$@"}
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
# func_mode_finish arg...
func_mode_finish ()
{
$opt_debug
- libdirs="$nonopt"
+ libs=
+ libdirs=
admincmds=
- if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
- for dir
- do
- libdirs="$libdirs $dir"
- done
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "\`$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument \`$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
for libdir in $libdirs; do
if test -n "$finish_cmds"; then
# Do each command in the finish commands.
@@ -1986,7 +2704,7 @@
if test -n "$finish_eval"; then
# Do the single finish_eval.
eval cmds=\"$finish_eval\"
- $opt_dry_run || eval "$cmds" || admincmds="$admincmds
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
$cmds"
fi
done
@@ -1995,53 +2713,55 @@
# Exit here if they wanted silent mode.
$opt_silent && exit $EXIT_SUCCESS
- echo "----------------------------------------------------------------------"
- echo "Libraries have been installed in:"
- for libdir in $libdirs; do
- $ECHO " $libdir"
- done
- echo
- echo "If you ever happen to want to link against installed libraries"
- echo "in a given directory, LIBDIR, you must either use libtool, and"
- echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
- echo "flag during linking and do at least one of the following:"
- if test -n "$shlibpath_var"; then
- echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
- echo " during execution"
- fi
- if test -n "$runpath_var"; then
- echo " - add LIBDIR to the \`$runpath_var' environment variable"
- echo " during linking"
- fi
- if test -n "$hardcode_libdir_flag_spec"; then
- libdir=LIBDIR
- eval flag=\"$hardcode_libdir_flag_spec\"
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
- $ECHO " - use the \`$flag' linker flag"
- fi
- if test -n "$admincmds"; then
- $ECHO " - have your system administrator run these commands:$admincmds"
- fi
- if test -f /etc/ld.so.conf; then
- echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
- fi
- echo
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
- echo "See any operating system documentation about shared libraries for"
- case $host in
- solaris2.[6789]|solaris2.1[0-9])
- echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
- echo "pages."
- ;;
- *)
- echo "more information, such as the ld(1) and ld.so(8) manual pages."
- ;;
- esac
- echo "----------------------------------------------------------------------"
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
exit $EXIT_SUCCESS
}
-test "$mode" = finish && func_mode_finish ${1+"$@"}
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
# func_mode_install arg...
@@ -2066,7 +2786,7 @@
# The real first argument should be the name of the installation program.
# Aesthetically quote it.
func_quote_for_eval "$arg"
- install_prog="$install_prog$func_quote_for_eval_result"
+ func_append install_prog "$func_quote_for_eval_result"
install_shared_prog=$install_prog
case " $install_prog " in
*[\\\ /]cp\ *) install_cp=: ;;
@@ -2086,7 +2806,7 @@
do
arg2=
if test -n "$dest"; then
- files="$files $dest"
+ func_append files " $dest"
dest=$arg
continue
fi
@@ -2124,11 +2844,11 @@
# Aesthetically quote the argument.
func_quote_for_eval "$arg"
- install_prog="$install_prog $func_quote_for_eval_result"
+ func_append install_prog " $func_quote_for_eval_result"
if test -n "$arg2"; then
func_quote_for_eval "$arg2"
fi
- install_shared_prog="$install_shared_prog $func_quote_for_eval_result"
+ func_append install_shared_prog " $func_quote_for_eval_result"
done
test -z "$install_prog" && \
@@ -2140,7 +2860,7 @@
if test -n "$install_override_mode" && $no_mode; then
if $install_cp; then :; else
func_quote_for_eval "$install_override_mode"
- install_shared_prog="$install_shared_prog -m $func_quote_for_eval_result"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
fi
fi
@@ -2198,10 +2918,13 @@
case $file in
*.$libext)
# Do the static libraries later.
- staticlibs="$staticlibs $file"
+ func_append staticlibs " $file"
;;
*.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
# Check to see that this really is a libtool archive.
func_lalib_unsafe_p "$file" \
|| func_fatal_help "\`$file' is not a valid libtool archive"
@@ -2215,19 +2938,19 @@
if test "X$destdir" = "X$libdir"; then
case "$current_libdirs " in
*" $libdir "*) ;;
- *) current_libdirs="$current_libdirs $libdir" ;;
+ *) func_append current_libdirs " $libdir" ;;
esac
else
# Note the libdir as a future libdir.
case "$future_libdirs " in
*" $libdir "*) ;;
- *) future_libdirs="$future_libdirs $libdir" ;;
+ *) func_append future_libdirs " $libdir" ;;
esac
fi
func_dirname "$file" "/" ""
dir="$func_dirname_result"
- dir="$dir$objdir"
+ func_append dir "$objdir"
if test -n "$relink_command"; then
# Determine the prefix the user has applied to our future dir.
@@ -2304,7 +3027,7 @@
func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
# Maybe install the static library, too.
- test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
;;
*.lo)
@@ -2501,7 +3224,7 @@
fi
}
-test "$mode" = install && func_mode_install ${1+"$@"}
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
# func_generate_dlsyms outputname originator pic_p
@@ -2548,6 +3271,18 @@
#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
#endif
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
/* External symbol declarations for the compiler. */\
"
@@ -2559,8 +3294,9 @@
# Add our own program objects to the symbol list.
progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
for progfile in $progfiles; do
- func_verbose "extracting global C symbols from \`$progfile'"
- $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
done
if test -n "$exclude_expsyms"; then
@@ -2609,10 +3345,52 @@
func_verbose "extracting global C symbols from \`$dlprefile'"
func_basename "$dlprefile"
name="$func_basename_result"
- $opt_dry_run || {
- eval '$ECHO ": $name " >> "$nlist"'
- eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
- }
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=""
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname" ; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename="$func_basename_result"
+ else
+ # no lafile. user explicitly requested -dlpreopen .
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename" ; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
done
$opt_dry_run || {
@@ -2650,26 +3428,9 @@
const char *name;
void *address;
} lt_dlsymlist;
-"
- case $host in
- *cygwin* | *mingw* | *cegcc* )
- echo >> "$output_objdir/$my_dlsyms" "\
-/* DATA imports from DLLs on WIN32 con't be const, because
- runtime relocations are performed -- see ld's documentation
- on pseudo-relocs. */"
- lt_dlsym_const= ;;
- *osf5*)
- echo >> "$output_objdir/$my_dlsyms" "\
-/* This system does not cope well with relocations in const data */"
- lt_dlsym_const= ;;
- *)
- lt_dlsym_const=const ;;
- esac
-
- echo >> "$output_objdir/$my_dlsyms" "\
-extern $lt_dlsym_const lt_dlsymlist
+extern LT_DLSYM_CONST lt_dlsymlist
lt_${my_prefix}_LTX_preloaded_symbols[];
-$lt_dlsym_const lt_dlsymlist
+LT_DLSYM_CONST lt_dlsymlist
lt_${my_prefix}_LTX_preloaded_symbols[] =
{\
{ \"$my_originator\", (void *) 0 },"
@@ -2725,7 +3486,7 @@
for arg in $LTCFLAGS; do
case $arg in
-pie | -fpie | -fPIE) ;;
- *) symtab_cflags="$symtab_cflags $arg" ;;
+ *) func_append symtab_cflags " $arg" ;;
esac
done
@@ -2788,7 +3549,8 @@
# Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
$EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
- win32_nmres=`eval $NM -f posix -A $1 |
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
$SED -n -e '
1,100{
/ I /{
@@ -2817,6 +3579,131 @@
$ECHO "$win32_libid_type"
}
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $opt_debug
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $opt_debug
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive which possess that section. Heuristic: eliminate
+ # all those which have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $opt_debug
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $opt_debug
+ if func_cygming_gnu_implib_p "$1" ; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1" ; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=""
+ fi
+}
# func_extract_an_archive dir oldlib
@@ -3195,6 +4082,18 @@
if test -f \"\$progdir/\$program\"; then"
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
# Export our shlibpath_var if we have one.
if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
$ECHO "\
@@ -3209,14 +4108,6 @@
"
fi
- # fixup the dll searchpath if we need to.
- if test -n "$dllsearchpath"; then
- $ECHO "\
- # Add the dll search path components to the executable PATH
- PATH=$dllsearchpath:\$PATH
-"
- fi
-
$ECHO "\
if test \"\$libtool_execute_magic\" != \"$magic\"; then
# Run the actual program with our arguments.
@@ -3234,166 +4125,6 @@
}
-# func_to_host_path arg
-#
-# Convert paths to host format when used with build tools.
-# Intended for use with "native" mingw (where libtool itself
-# is running under the msys shell), or in the following cross-
-# build environments:
-# $build $host
-# mingw (msys) mingw [e.g. native]
-# cygwin mingw
-# *nix + wine mingw
-# where wine is equipped with the `winepath' executable.
-# In the native mingw case, the (msys) shell automatically
-# converts paths for any non-msys applications it launches,
-# but that facility isn't available from inside the cwrapper.
-# Similar accommodations are necessary for $host mingw and
-# $build cygwin. Calling this function does no harm for other
-# $host/$build combinations not listed above.
-#
-# ARG is the path (on $build) that should be converted to
-# the proper representation for $host. The result is stored
-# in $func_to_host_path_result.
-func_to_host_path ()
-{
- func_to_host_path_result="$1"
- if test -n "$1"; then
- case $host in
- *mingw* )
- lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
- case $build in
- *mingw* ) # actually, msys
- # awkward: cmd appends spaces to result
- func_to_host_path_result=`( cmd //c echo "$1" ) 2>/dev/null |
- $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
- ;;
- *cygwin* )
- func_to_host_path_result=`cygpath -w "$1" |
- $SED -e "$lt_sed_naive_backslashify"`
- ;;
- * )
- # Unfortunately, winepath does not exit with a non-zero
- # error code, so we are forced to check the contents of
- # stdout. On the other hand, if the command is not
- # found, the shell will set an exit code of 127 and print
- # *an error message* to stdout. So we must check for both
- # error code of zero AND non-empty stdout, which explains
- # the odd construction:
- func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
- if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
- func_to_host_path_result=`$ECHO "$func_to_host_path_tmp1" |
- $SED -e "$lt_sed_naive_backslashify"`
- else
- # Allow warning below.
- func_to_host_path_result=
- fi
- ;;
- esac
- if test -z "$func_to_host_path_result" ; then
- func_error "Could not determine host path corresponding to"
- func_error " \`$1'"
- func_error "Continuing, but uninstalled executables may not work."
- # Fallback:
- func_to_host_path_result="$1"
- fi
- ;;
- esac
- fi
-}
-# end: func_to_host_path
-
-# func_to_host_pathlist arg
-#
-# Convert pathlists to host format when used with build tools.
-# See func_to_host_path(), above. This function supports the
-# following $build/$host combinations (but does no harm for
-# combinations not listed here):
-# $build $host
-# mingw (msys) mingw [e.g. native]
-# cygwin mingw
-# *nix + wine mingw
-#
-# Path separators are also converted from $build format to
-# $host format. If ARG begins or ends with a path separator
-# character, it is preserved (but converted to $host format)
-# on output.
-#
-# ARG is a pathlist (on $build) that should be converted to
-# the proper representation on $host. The result is stored
-# in $func_to_host_pathlist_result.
-func_to_host_pathlist ()
-{
- func_to_host_pathlist_result="$1"
- if test -n "$1"; then
- case $host in
- *mingw* )
- lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
- # Remove leading and trailing path separator characters from
- # ARG. msys behavior is inconsistent here, cygpath turns them
- # into '.;' and ';.', and winepath ignores them completely.
- func_stripname : : "$1"
- func_to_host_pathlist_tmp1=$func_stripname_result
- case $build in
- *mingw* ) # Actually, msys.
- # Awkward: cmd appends spaces to result.
- func_to_host_pathlist_result=`
- ( cmd //c echo "$func_to_host_pathlist_tmp1" ) 2>/dev/null |
- $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
- ;;
- *cygwin* )
- func_to_host_pathlist_result=`cygpath -w -p "$func_to_host_pathlist_tmp1" |
- $SED -e "$lt_sed_naive_backslashify"`
- ;;
- * )
- # unfortunately, winepath doesn't convert pathlists
- func_to_host_pathlist_result=""
- func_to_host_pathlist_oldIFS=$IFS
- IFS=:
- for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
- IFS=$func_to_host_pathlist_oldIFS
- if test -n "$func_to_host_pathlist_f" ; then
- func_to_host_path "$func_to_host_pathlist_f"
- if test -n "$func_to_host_path_result" ; then
- if test -z "$func_to_host_pathlist_result" ; then
- func_to_host_pathlist_result="$func_to_host_path_result"
- else
- func_append func_to_host_pathlist_result ";$func_to_host_path_result"
- fi
- fi
- fi
- done
- IFS=$func_to_host_pathlist_oldIFS
- ;;
- esac
- if test -z "$func_to_host_pathlist_result"; then
- func_error "Could not determine the host path(s) corresponding to"
- func_error " \`$1'"
- func_error "Continuing, but uninstalled executables may not work."
- # Fallback. This may break if $1 contains DOS-style drive
- # specifications. The fix is not to complicate the expression
- # below, but for the user to provide a working wine installation
- # with winepath so that path translation in the cross-to-mingw
- # case works properly.
- lt_replace_pathsep_nix_to_dos="s|:|;|g"
- func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
- $SED -e "$lt_replace_pathsep_nix_to_dos"`
- fi
- # Now, add the leading and trailing path separators back
- case "$1" in
- :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
- ;;
- esac
- case "$1" in
- *: ) func_append func_to_host_pathlist_result ";"
- ;;
- esac
- ;;
- esac
- fi
-}
-# end: func_to_host_pathlist
-
# func_emit_cwrapperexe_src
# emit the source code for a wrapper executable on stdout
# Must ONLY be called from within func_mode_link because
@@ -3563,14 +4294,14 @@
EOF
cat </dev/null`
+ if test "$want_nocaseglob" = yes; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
for potent_lib in $potential_libs; do
# Follow soft links.
if ls -lLd "$potent_lib" 2>/dev/null |
@@ -6999,7 +7812,7 @@
if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
$SED -e 10q |
$EGREP "$file_magic_regex" > /dev/null; then
- newdeplibs="$newdeplibs $a_deplib"
+ func_append newdeplibs " $a_deplib"
a_deplib=""
break 2
fi
@@ -7024,7 +7837,7 @@
;;
*)
# Add a -L argument.
- newdeplibs="$newdeplibs $a_deplib"
+ func_append newdeplibs " $a_deplib"
;;
esac
done # Gone through all deplibs.
@@ -7040,7 +7853,7 @@
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
*" $a_deplib "*)
- newdeplibs="$newdeplibs $a_deplib"
+ func_append newdeplibs " $a_deplib"
a_deplib=""
;;
esac
@@ -7053,7 +7866,7 @@
potlib="$potent_lib" # see symlink-check above in file_magic test
if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
$EGREP "$match_pattern_regex" > /dev/null; then
- newdeplibs="$newdeplibs $a_deplib"
+ func_append newdeplibs " $a_deplib"
a_deplib=""
break 2
fi
@@ -7078,7 +7891,7 @@
;;
*)
# Add a -L argument.
- newdeplibs="$newdeplibs $a_deplib"
+ func_append newdeplibs " $a_deplib"
;;
esac
done # Gone through all deplibs.
@@ -7182,7 +7995,7 @@
*)
case " $deplibs " in
*" -L$path/$objdir "*)
- new_libs="$new_libs -L$path/$objdir" ;;
+ func_append new_libs " -L$path/$objdir" ;;
esac
;;
esac
@@ -7192,10 +8005,10 @@
-L*)
case " $new_libs " in
*" $deplib "*) ;;
- *) new_libs="$new_libs $deplib" ;;
+ *) func_append new_libs " $deplib" ;;
esac
;;
- *) new_libs="$new_libs $deplib" ;;
+ *) func_append new_libs " $deplib" ;;
esac
done
deplibs="$new_libs"
@@ -7212,10 +8025,12 @@
hardcode_libdirs=
dep_rpath=
rpath="$finalize_rpath"
- test "$mode" != relink && rpath="$compile_rpath$rpath"
+ test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
for libdir in $rpath; do
if test -n "$hardcode_libdir_flag_spec"; then
if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
if test -z "$hardcode_libdirs"; then
hardcode_libdirs="$libdir"
else
@@ -7224,18 +8039,18 @@
*"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
;;
*)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
;;
esac
fi
else
eval flag=\"$hardcode_libdir_flag_spec\"
- dep_rpath="$dep_rpath $flag"
+ func_append dep_rpath " $flag"
fi
elif test -n "$runpath_var"; then
case "$perm_rpath " in
*" $libdir "*) ;;
- *) perm_rpath="$perm_rpath $libdir" ;;
+ *) func_apped perm_rpath " $libdir" ;;
esac
fi
done
@@ -7253,7 +8068,7 @@
# We should set the runpath_var.
rpath=
for dir in $perm_rpath; do
- rpath="$rpath$dir:"
+ func_append rpath "$dir:"
done
eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
fi
@@ -7261,7 +8076,7 @@
fi
shlibpath="$finalize_shlibpath"
- test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
if test -n "$shlibpath"; then
eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
fi
@@ -7287,7 +8102,7 @@
linknames=
for link
do
- linknames="$linknames $link"
+ func_append linknames " $link"
done
# Use standard objects if they are pic
@@ -7298,7 +8113,7 @@
if test -n "$export_symbols" && test -n "$include_expsyms"; then
$opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
export_symbols="$output_objdir/$libname.uexp"
- delfiles="$delfiles $export_symbols"
+ func_append delfiles " $export_symbols"
fi
orig_export_symbols=
@@ -7329,13 +8144,45 @@
$opt_dry_run || $RM $export_symbols
cmds=$export_symbols_cmds
save_ifs="$IFS"; IFS='~'
- for cmd in $cmds; do
+ for cmd1 in $cmds; do
IFS="$save_ifs"
- eval cmd=\"$cmd\"
- func_len " $cmd"
- len=$func_len_result
- if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test "$try_normal_branch" = yes \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=${output_objdir}/${output_la}.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
skipped_export=false
else
# The command line is too long to execute in one step.
@@ -7369,7 +8216,7 @@
# global variables. join(1) would be nice here, but unfortunately
# isn't a blessed tool.
$opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
- delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
export_symbols=$output_objdir/$libname.def
$opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
fi
@@ -7379,7 +8226,7 @@
case " $convenience " in
*" $test_deplib "*) ;;
*)
- tmp_deplibs="$tmp_deplibs $test_deplib"
+ func_append tmp_deplibs " $test_deplib"
;;
esac
done
@@ -7399,21 +8246,21 @@
test "X$libobjs" = "X " && libobjs=
else
gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_extract_archives $gentop $convenience
- libobjs="$libobjs $func_extract_archives_result"
+ func_append libobjs " $func_extract_archives_result"
test "X$libobjs" = "X " && libobjs=
fi
fi
if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
eval flag=\"$thread_safe_flag_spec\"
- linker_flags="$linker_flags $flag"
+ func_append linker_flags " $flag"
fi
# Make a backup of the uninstalled library when relinking
- if test "$mode" = relink; then
+ if test "$opt_mode" = relink; then
$opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
fi
@@ -7475,10 +8322,13 @@
echo 'INPUT (' > $output
for obj in $save_libobjs
do
- $ECHO "$obj" >> $output
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
done
echo ')' >> $output
- delfiles="$delfiles $output"
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
output=${output_objdir}/${output_la}.lnk
func_verbose "creating linker input file list: $output"
@@ -7492,10 +8342,12 @@
fi
for obj
do
- $ECHO "$obj" >> $output
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
done
- delfiles="$delfiles $output"
- output=$firstobj\"$file_list_spec$output\"
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
else
if test -n "$save_libobjs"; then
func_verbose "creating reloadable object files..."
@@ -7546,7 +8398,7 @@
if test -n "$last_robj"; then
eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
fi
- delfiles="$delfiles $output"
+ func_append delfiles " $output"
else
output=
@@ -7580,7 +8432,7 @@
lt_exit=$?
# Restore the uninstalled library and exit
- if test "$mode" = relink; then
+ if test "$opt_mode" = relink; then
( cd "$output_objdir" && \
$RM "${realname}T" && \
$MV "${realname}U" "$realname" )
@@ -7613,7 +8465,7 @@
# global variables. join(1) would be nice here, but unfortunately
# isn't a blessed tool.
$opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
- delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
export_symbols=$output_objdir/$libname.def
$opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
fi
@@ -7654,10 +8506,10 @@
# Add any objects from preloaded convenience libraries
if test -n "$dlprefiles"; then
gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_extract_archives $gentop $dlprefiles
- libobjs="$libobjs $func_extract_archives_result"
+ func_append libobjs " $func_extract_archives_result"
test "X$libobjs" = "X " && libobjs=
fi
@@ -7673,7 +8525,7 @@
lt_exit=$?
# Restore the uninstalled library and exit
- if test "$mode" = relink; then
+ if test "$opt_mode" = relink; then
( cd "$output_objdir" && \
$RM "${realname}T" && \
$MV "${realname}U" "$realname" )
@@ -7685,7 +8537,7 @@
IFS="$save_ifs"
# Restore the uninstalled library and exit
- if test "$mode" = relink; then
+ if test "$opt_mode" = relink; then
$opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
if test -n "$convenience"; then
@@ -7769,13 +8621,16 @@
reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
else
gentop="$output_objdir/${obj}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_extract_archives $gentop $convenience
reload_conv_objs="$reload_objs $func_extract_archives_result"
fi
fi
+ # If we're not building shared, we need to use non_pic_objs
+ test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
# Create the old-style object.
reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
@@ -7849,8 +8704,8 @@
if test "$tagname" = CXX ; then
case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
10.[0123])
- compile_command="$compile_command ${wl}-bind_at_load"
- finalize_command="$finalize_command ${wl}-bind_at_load"
+ func_append compile_command " ${wl}-bind_at_load"
+ func_append finalize_command " ${wl}-bind_at_load"
;;
esac
fi
@@ -7870,7 +8725,7 @@
*)
case " $compile_deplibs " in
*" -L$path/$objdir "*)
- new_libs="$new_libs -L$path/$objdir" ;;
+ func_append new_libs " -L$path/$objdir" ;;
esac
;;
esac
@@ -7880,17 +8735,17 @@
-L*)
case " $new_libs " in
*" $deplib "*) ;;
- *) new_libs="$new_libs $deplib" ;;
+ *) func_append new_libs " $deplib" ;;
esac
;;
- *) new_libs="$new_libs $deplib" ;;
+ *) func_append new_libs " $deplib" ;;
esac
done
compile_deplibs="$new_libs"
- compile_command="$compile_command $compile_deplibs"
- finalize_command="$finalize_command $finalize_deplibs"
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
if test -n "$rpath$xrpath"; then
# If the user specified any rpath flags, then add them.
@@ -7898,7 +8753,7 @@
# This is the magic to use -rpath.
case "$finalize_rpath " in
*" $libdir "*) ;;
- *) finalize_rpath="$finalize_rpath $libdir" ;;
+ *) func_append finalize_rpath " $libdir" ;;
esac
done
fi
@@ -7917,18 +8772,18 @@
*"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
;;
*)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
;;
esac
fi
else
eval flag=\"$hardcode_libdir_flag_spec\"
- rpath="$rpath $flag"
+ func_append rpath " $flag"
fi
elif test -n "$runpath_var"; then
case "$perm_rpath " in
*" $libdir "*) ;;
- *) perm_rpath="$perm_rpath $libdir" ;;
+ *) func_append perm_rpath " $libdir" ;;
esac
fi
case $host in
@@ -7937,12 +8792,12 @@
case :$dllsearchpath: in
*":$libdir:"*) ;;
::) dllsearchpath=$libdir;;
- *) dllsearchpath="$dllsearchpath:$libdir";;
+ *) func_append dllsearchpath ":$libdir";;
esac
case :$dllsearchpath: in
*":$testbindir:"*) ;;
::) dllsearchpath=$testbindir;;
- *) dllsearchpath="$dllsearchpath:$testbindir";;
+ *) func_append dllsearchpath ":$testbindir";;
esac
;;
esac
@@ -7968,18 +8823,18 @@
*"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
;;
*)
- hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
;;
esac
fi
else
eval flag=\"$hardcode_libdir_flag_spec\"
- rpath="$rpath $flag"
+ func_append rpath " $flag"
fi
elif test -n "$runpath_var"; then
case "$finalize_perm_rpath " in
*" $libdir "*) ;;
- *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
esac
fi
done
@@ -8030,6 +8885,12 @@
exit_status=0
func_show_eval "$link_command" 'exit_status=$?'
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
# Delete the generated files.
if test -f "$output_objdir/${outputname}S.${objext}"; then
func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
@@ -8052,7 +8913,7 @@
# We should set the runpath_var.
rpath=
for dir in $perm_rpath; do
- rpath="$rpath$dir:"
+ func_append rpath "$dir:"
done
compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
fi
@@ -8060,7 +8921,7 @@
# We should set the runpath_var.
rpath=
for dir in $finalize_perm_rpath; do
- rpath="$rpath$dir:"
+ func_append rpath "$dir:"
done
finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
fi
@@ -8075,6 +8936,13 @@
$opt_dry_run || $RM $output
# Link the executable and exit
func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
exit $EXIT_SUCCESS
fi
@@ -8108,6 +8976,12 @@
func_show_eval "$link_command" 'exit $?'
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
# Now create the wrapper script.
func_verbose "creating $output"
@@ -8205,7 +9079,7 @@
else
oldobjs="$old_deplibs $non_pic_objects"
if test "$preload" = yes && test -f "$symfileobj"; then
- oldobjs="$oldobjs $symfileobj"
+ func_append oldobjs " $symfileobj"
fi
fi
addlibs="$old_convenience"
@@ -8213,10 +9087,10 @@
if test -n "$addlibs"; then
gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_extract_archives $gentop $addlibs
- oldobjs="$oldobjs $func_extract_archives_result"
+ func_append oldobjs " $func_extract_archives_result"
fi
# Do each command in the archive commands.
@@ -8227,10 +9101,10 @@
# Add any objects from preloaded convenience libraries
if test -n "$dlprefiles"; then
gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_extract_archives $gentop $dlprefiles
- oldobjs="$oldobjs $func_extract_archives_result"
+ func_append oldobjs " $func_extract_archives_result"
fi
# POSIX demands no paths to be encoded in archives. We have
@@ -8248,7 +9122,7 @@
else
echo "copying selected object files to avoid basename conflicts..."
gentop="$output_objdir/${outputname}x"
- generated="$generated $gentop"
+ func_append generated " $gentop"
func_mkdir_p "$gentop"
save_oldobjs=$oldobjs
oldobjs=
@@ -8272,9 +9146,9 @@
esac
done
func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
- oldobjs="$oldobjs $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
;;
- *) oldobjs="$oldobjs $obj" ;;
+ *) func_append oldobjs " $obj" ;;
esac
done
fi
@@ -8284,6 +9158,16 @@
len=$func_len_result
if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
else
# the command line is too long to link in one step, link in parts
func_verbose "using piecewise archive linking..."
@@ -8380,9 +9264,19 @@
eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
test -z "$libdir" && \
func_fatal_error "\`$deplib' is not a valid libtool archive"
- newdependency_libs="$newdependency_libs $libdir/$name"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
;;
- *) newdependency_libs="$newdependency_libs $deplib" ;;
+ *) func_append newdependency_libs " $deplib" ;;
esac
done
dependency_libs="$newdependency_libs"
@@ -8396,9 +9290,9 @@
eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
test -z "$libdir" && \
func_fatal_error "\`$lib' is not a valid libtool archive"
- newdlfiles="$newdlfiles $libdir/$name"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
;;
- *) newdlfiles="$newdlfiles $lib" ;;
+ *) func_append newdlfiles " $lib" ;;
esac
done
dlfiles="$newdlfiles"
@@ -8415,7 +9309,7 @@
eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
test -z "$libdir" && \
func_fatal_error "\`$lib' is not a valid libtool archive"
- newdlprefiles="$newdlprefiles $libdir/$name"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
;;
esac
done
@@ -8427,7 +9321,7 @@
[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
*) abs=`pwd`"/$lib" ;;
esac
- newdlfiles="$newdlfiles $abs"
+ func_append newdlfiles " $abs"
done
dlfiles="$newdlfiles"
newdlprefiles=
@@ -8436,7 +9330,7 @@
[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
*) abs=`pwd`"/$lib" ;;
esac
- newdlprefiles="$newdlprefiles $abs"
+ func_append newdlprefiles " $abs"
done
dlprefiles="$newdlprefiles"
fi
@@ -8521,7 +9415,7 @@
exit $EXIT_SUCCESS
}
-{ test "$mode" = link || test "$mode" = relink; } &&
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
func_mode_link ${1+"$@"}
@@ -8541,9 +9435,9 @@
for arg
do
case $arg in
- -f) RM="$RM $arg"; rmforce=yes ;;
- -*) RM="$RM $arg" ;;
- *) files="$files $arg" ;;
+ -f) func_append RM " $arg"; rmforce=yes ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
esac
done
@@ -8552,24 +9446,23 @@
rmdirs=
- origobjdir="$objdir"
for file in $files; do
func_dirname "$file" "" "."
dir="$func_dirname_result"
if test "X$dir" = X.; then
- objdir="$origobjdir"
+ odir="$objdir"
else
- objdir="$dir/$origobjdir"
+ odir="$dir/$objdir"
fi
func_basename "$file"
name="$func_basename_result"
- test "$mode" = uninstall && objdir="$dir"
+ test "$opt_mode" = uninstall && odir="$dir"
- # Remember objdir for removal later, being careful to avoid duplicates
- if test "$mode" = clean; then
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test "$opt_mode" = clean; then
case " $rmdirs " in
- *" $objdir "*) ;;
- *) rmdirs="$rmdirs $objdir" ;;
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
esac
fi
@@ -8595,18 +9488,17 @@
# Delete the libtool libraries and symlinks.
for n in $library_names; do
- rmfiles="$rmfiles $objdir/$n"
+ func_append rmfiles " $odir/$n"
done
- test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
- case "$mode" in
+ case "$opt_mode" in
clean)
- case " $library_names " in
- # " " in the beginning catches empty $dlname
+ case " $library_names " in
*" $dlname "*) ;;
- *) rmfiles="$rmfiles $objdir/$dlname" ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
esac
- test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
;;
uninstall)
if test -n "$library_names"; then
@@ -8634,19 +9526,19 @@
# Add PIC object to the list of files to remove.
if test -n "$pic_object" &&
test "$pic_object" != none; then
- rmfiles="$rmfiles $dir/$pic_object"
+ func_append rmfiles " $dir/$pic_object"
fi
# Add non-PIC object to the list of files to remove.
if test -n "$non_pic_object" &&
test "$non_pic_object" != none; then
- rmfiles="$rmfiles $dir/$non_pic_object"
+ func_append rmfiles " $dir/$non_pic_object"
fi
fi
;;
*)
- if test "$mode" = clean ; then
+ if test "$opt_mode" = clean ; then
noexename=$name
case $file in
*.exe)
@@ -8656,7 +9548,7 @@
noexename=$func_stripname_result
# $file with .exe has already been added to rmfiles,
# add $file without .exe
- rmfiles="$rmfiles $file"
+ func_append rmfiles " $file"
;;
esac
# Do a test to see if this is a libtool program.
@@ -8665,7 +9557,7 @@
func_ltwrapper_scriptname "$file"
relink_command=
func_source $func_ltwrapper_scriptname_result
- rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
else
relink_command=
func_source $dir/$noexename
@@ -8673,12 +9565,12 @@
# note $name still contains .exe if it was in $file originally
# as does the version of $file that was added into $rmfiles
- rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+ func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
if test "$fast_install" = yes && test -n "$relink_command"; then
- rmfiles="$rmfiles $objdir/lt-$name"
+ func_append rmfiles " $odir/lt-$name"
fi
if test "X$noexename" != "X$name" ; then
- rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+ func_append rmfiles " $odir/lt-${noexename}.c"
fi
fi
fi
@@ -8686,7 +9578,6 @@
esac
func_show_eval "$RM $rmfiles" 'exit_status=1'
done
- objdir="$origobjdir"
# Try to remove the ${objdir}s in the directories where we deleted files
for dir in $rmdirs; do
@@ -8698,16 +9589,16 @@
exit $exit_status
}
-{ test "$mode" = uninstall || test "$mode" = clean; } &&
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
func_mode_uninstall ${1+"$@"}
-test -z "$mode" && {
+test -z "$opt_mode" && {
help="$generic_help"
func_fatal_help "you must specify a MODE"
}
test -z "$exec_cmd" && \
- func_fatal_help "invalid operation mode \`$mode'"
+ func_fatal_help "invalid operation mode \`$opt_mode'"
if test -n "$exec_cmd"; then
eval exec "$exec_cmd"
diff -Nru pcre3-8.12/makevp_c.txt pcre3-8.31/makevp_c.txt
--- pcre3-8.12/makevp_c.txt 2008-09-05 10:21:21.000000000 +0000
+++ pcre3-8.31/makevp_c.txt 2011-12-28 16:57:51.000000000 +0000
@@ -1,3 +1,4 @@
+pcre_byte_order.c
pcre_chartables.c
pcre_compile.c
pcre_config.c
@@ -13,7 +14,6 @@
pcre_refcount.c
pcre_study.c
pcre_tables.c
-pcre_try_flipped.c
pcre_ucd.c
pcre_valid_utf8.c
pcre_version.c
diff -Nru pcre3-8.12/makevp_l.txt pcre3-8.31/makevp_l.txt
--- pcre3-8.12/makevp_l.txt 2008-09-05 10:21:47.000000000 +0000
+++ pcre3-8.31/makevp_l.txt 2011-12-28 16:57:55.000000000 +0000
@@ -1,3 +1,4 @@
++pcre_byte_order.obj &
+pcre_chartables.obj &
+pcre_compile.obj &
+pcre_config.obj &
@@ -13,7 +14,6 @@
+pcre_refcount.obj &
+pcre_study.obj &
+pcre_tables.obj &
-+pcre_try_flipped.obj &
+pcre_ucd.obj &
+pcre_valid_utf8.obj &
+pcre_version.obj &
diff -Nru pcre3-8.12/pcre-config.in pcre3-8.31/pcre-config.in
--- pcre3-8.12/pcre-config.in 2010-03-02 11:08:45.000000000 +0000
+++ pcre3-8.31/pcre-config.in 2012-01-21 16:00:28.000000000 +0000
@@ -4,12 +4,25 @@
exec_prefix=@exec_prefix@
exec_prefix_set=no
+cflags="[--cflags]"
+
if test @enable_cpp@ = yes ; then
- usage="Usage: pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs-posix] [--libs-cpp] [--cflags] [--cflags-posix]"
+ libs="[--libs-cpp]"
else
- usage="Usage: pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs-posix] [--cflags] [--cflags-posix]"
+ libs=
+fi
+
+if test @enable_pcre16@ = yes ; then
+ libs="[--libs16] $libs"
fi
+if test @enable_pcre8@ = yes ; then
+ libs="[--libs] [--libs-posix] $libs"
+ cflags="$cflags [--cflags-posix]"
+fi
+
+usage="Usage: pcre-config [--prefix] [--exec-prefix] [--version] $libs $cflags"
+
if test $# -eq 0; then
echo "${usage}" 1>&2
exit 1
@@ -25,6 +38,11 @@
;;
esac
+libS=
+if test @libdir@ != /usr/lib ; then
+ libS=-L@libdir@
+fi
+
while test $# -gt 0; do
case "$1" in
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
@@ -51,21 +69,46 @@
--version)
echo @PACKAGE_VERSION@
;;
- --cflags | --cflags-posix)
+ --cflags)
if test @includedir@ != /usr/include ; then
includes=-I@includedir@
fi
echo $includes @PCRE_STATIC_CFLAG@
;;
+ --cflags-posix)
+ if test @enable_pcre8@ = yes ; then
+ if test @includedir@ != /usr/include ; then
+ includes=-I@includedir@
+ fi
+ echo $includes @PCRE_STATIC_CFLAG@
+ else
+ echo "${usage}" 1>&2
+ fi
+ ;;
--libs-posix)
- echo -L@libdir@$libR -lpcreposix -lpcre
+ if test @enable_pcre8@ = yes ; then
+ echo $libS$libR -lpcreposix -lpcre
+ else
+ echo "${usage}" 1>&2
+ fi
;;
--libs)
- echo -L@libdir@$libR -lpcre
+ if test @enable_pcre8@ = yes ; then
+ echo $libS$libR -lpcre
+ else
+ echo "${usage}" 1>&2
+ fi
+ ;;
+ --libs16)
+ if test @enable_pcre16@ = yes ; then
+ echo $libS$libR -lpcre16
+ else
+ echo "${usage}" 1>&2
+ fi
;;
--libs-cpp)
if test @enable_cpp@ = yes ; then
- echo -L@libdir@$libR -lpcrecpp -lpcre
+ echo $libS$libR -lpcrecpp -lpcre
else
echo "${usage}" 1>&2
fi
diff -Nru pcre3-8.12/pcre.h.generic pcre3-8.31/pcre.h.generic
--- pcre3-8.12/pcre.h.generic 2011-01-15 17:27:55.000000000 +0000
+++ pcre3-8.31/pcre.h.generic 2012-07-06 09:55:37.000000000 +0000
@@ -5,7 +5,7 @@
/* This is the public header file for the PCRE library, to be #included by
applications that call the PCRE functions.
- Copyright (c) 1997-2010 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -42,9 +42,9 @@
/* The current PCRE version information. */
#define PCRE_MAJOR 8
-#define PCRE_MINOR 12
+#define PCRE_MINOR 31
#define PCRE_PRERELEASE
-#define PCRE_DATE 2011-01-15
+#define PCRE_DATE 2012-07-06
/* When an application links to a PCRE DLL in Windows, the symbols that are
imported have to be identified as such. When building PCRE, the appropriate
@@ -98,28 +98,37 @@
/* Options. Some are compile-time only, some are run-time only, and some are
both, so we keep them all distinct. However, almost all the bits in the options
word are now used. In the long run, we may have to re-use some of the
-compile-time only bits for runtime options, or vice versa. */
+compile-time only bits for runtime options, or vice versa. In the comments
+below, "compile", "exec", and "DFA exec" mean that the option is permitted to
+be set for those functions; "used in" means that an option may be set only for
+compile, but is subsequently referenced in exec and/or DFA exec. Any of the
+compile-time options may be inspected during studying (and therefore JIT
+compiling). */
#define PCRE_CASELESS 0x00000001 /* Compile */
#define PCRE_MULTILINE 0x00000002 /* Compile */
#define PCRE_DOTALL 0x00000004 /* Compile */
#define PCRE_EXTENDED 0x00000008 /* Compile */
#define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */
-#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile */
+#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */
#define PCRE_EXTRA 0x00000040 /* Compile */
#define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */
#define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */
#define PCRE_UNGREEDY 0x00000200 /* Compile */
#define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */
-#define PCRE_UTF8 0x00000800 /* Compile */
+/* The next two are also used in exec and DFA exec */
+#define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */
+#define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */
#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */
-#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile, exec, DFA exec */
+/* The next two are also used in exec and DFA exec */
+#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */
+#define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */
#define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */
#define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */
#define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */
#define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */
#define PCRE_DFA_RESTART 0x00020000 /* DFA exec */
-#define PCRE_FIRSTLINE 0x00040000 /* Compile */
+#define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */
#define PCRE_DUPNAMES 0x00080000 /* Compile */
#define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */
#define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */
@@ -128,41 +137,82 @@
#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */
#define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */
#define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */
-#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile */
+#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */
#define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */
#define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */
#define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */
#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */
-#define PCRE_UCP 0x20000000 /* Compile */
+#define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */
/* Exec-time and get/set-time error codes */
-#define PCRE_ERROR_NOMATCH (-1)
-#define PCRE_ERROR_NULL (-2)
-#define PCRE_ERROR_BADOPTION (-3)
-#define PCRE_ERROR_BADMAGIC (-4)
-#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
-#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
-#define PCRE_ERROR_NOMEMORY (-6)
-#define PCRE_ERROR_NOSUBSTRING (-7)
-#define PCRE_ERROR_MATCHLIMIT (-8)
-#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
-#define PCRE_ERROR_BADUTF8 (-10)
-#define PCRE_ERROR_BADUTF8_OFFSET (-11)
-#define PCRE_ERROR_PARTIAL (-12)
-#define PCRE_ERROR_BADPARTIAL (-13)
-#define PCRE_ERROR_INTERNAL (-14)
-#define PCRE_ERROR_BADCOUNT (-15)
-#define PCRE_ERROR_DFA_UITEM (-16)
-#define PCRE_ERROR_DFA_UCOND (-17)
-#define PCRE_ERROR_DFA_UMLIMIT (-18)
-#define PCRE_ERROR_DFA_WSSIZE (-19)
-#define PCRE_ERROR_DFA_RECURSE (-20)
-#define PCRE_ERROR_RECURSIONLIMIT (-21)
-#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
-#define PCRE_ERROR_BADNEWLINE (-23)
-#define PCRE_ERROR_BADOFFSET (-24)
-#define PCRE_ERROR_SHORTUTF8 (-25)
+#define PCRE_ERROR_NOMATCH (-1)
+#define PCRE_ERROR_NULL (-2)
+#define PCRE_ERROR_BADOPTION (-3)
+#define PCRE_ERROR_BADMAGIC (-4)
+#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
+#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
+#define PCRE_ERROR_NOMEMORY (-6)
+#define PCRE_ERROR_NOSUBSTRING (-7)
+#define PCRE_ERROR_MATCHLIMIT (-8)
+#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
+#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */
+#define PCRE_ERROR_PARTIAL (-12)
+#define PCRE_ERROR_BADPARTIAL (-13)
+#define PCRE_ERROR_INTERNAL (-14)
+#define PCRE_ERROR_BADCOUNT (-15)
+#define PCRE_ERROR_DFA_UITEM (-16)
+#define PCRE_ERROR_DFA_UCOND (-17)
+#define PCRE_ERROR_DFA_UMLIMIT (-18)
+#define PCRE_ERROR_DFA_WSSIZE (-19)
+#define PCRE_ERROR_DFA_RECURSE (-20)
+#define PCRE_ERROR_RECURSIONLIMIT (-21)
+#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
+#define PCRE_ERROR_BADNEWLINE (-23)
+#define PCRE_ERROR_BADOFFSET (-24)
+#define PCRE_ERROR_SHORTUTF8 (-25)
+#define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */
+#define PCRE_ERROR_RECURSELOOP (-26)
+#define PCRE_ERROR_JIT_STACKLIMIT (-27)
+#define PCRE_ERROR_BADMODE (-28)
+#define PCRE_ERROR_BADENDIANNESS (-29)
+#define PCRE_ERROR_DFA_BADRESTART (-30)
+
+/* Specific error codes for UTF-8 validity checks */
+
+#define PCRE_UTF8_ERR0 0
+#define PCRE_UTF8_ERR1 1
+#define PCRE_UTF8_ERR2 2
+#define PCRE_UTF8_ERR3 3
+#define PCRE_UTF8_ERR4 4
+#define PCRE_UTF8_ERR5 5
+#define PCRE_UTF8_ERR6 6
+#define PCRE_UTF8_ERR7 7
+#define PCRE_UTF8_ERR8 8
+#define PCRE_UTF8_ERR9 9
+#define PCRE_UTF8_ERR10 10
+#define PCRE_UTF8_ERR11 11
+#define PCRE_UTF8_ERR12 12
+#define PCRE_UTF8_ERR13 13
+#define PCRE_UTF8_ERR14 14
+#define PCRE_UTF8_ERR15 15
+#define PCRE_UTF8_ERR16 16
+#define PCRE_UTF8_ERR17 17
+#define PCRE_UTF8_ERR18 18
+#define PCRE_UTF8_ERR19 19
+#define PCRE_UTF8_ERR20 20
+#define PCRE_UTF8_ERR21 21
+
+/* Specific error codes for UTF-16 validity checks */
+
+#define PCRE_UTF16_ERR0 0
+#define PCRE_UTF16_ERR1 1
+#define PCRE_UTF16_ERR2 2
+#define PCRE_UTF16_ERR3 3
+#define PCRE_UTF16_ERR4 4
/* Request types for pcre_fullinfo() */
@@ -183,6 +233,9 @@
#define PCRE_INFO_JCHANGED 13
#define PCRE_INFO_HASCRORLF 14
#define PCRE_INFO_MINLENGTH 15
+#define PCRE_INFO_JIT 16
+#define PCRE_INFO_JITSIZE 17
+#define PCRE_INFO_MAXLOOKBEHIND 18
/* Request types for pcre_config(). Do not re-arrange, in order to remain
compatible. */
@@ -196,8 +249,18 @@
#define PCRE_CONFIG_UNICODE_PROPERTIES 6
#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
#define PCRE_CONFIG_BSR 8
+#define PCRE_CONFIG_JIT 9
+#define PCRE_CONFIG_UTF16 10
+#define PCRE_CONFIG_JITTARGET 11
-/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine
+/* Request types for pcre_study(). Do not re-arrange, in order to remain
+compatible. */
+
+#define PCRE_STUDY_JIT_COMPILE 0x0001
+#define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002
+#define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004
+
+/* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine
these bits, just add new ones on the end, in order to remain compatible. */
#define PCRE_EXTRA_STUDY_DATA 0x0001
@@ -206,12 +269,33 @@
#define PCRE_EXTRA_TABLES 0x0008
#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
#define PCRE_EXTRA_MARK 0x0020
+#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040
/* Types */
struct real_pcre; /* declaration; the definition is private */
typedef struct real_pcre pcre;
+struct real_pcre16; /* declaration; the definition is private */
+typedef struct real_pcre16 pcre16;
+
+struct real_pcre_jit_stack; /* declaration; the definition is private */
+typedef struct real_pcre_jit_stack pcre_jit_stack;
+
+struct real_pcre16_jit_stack; /* declaration; the definition is private */
+typedef struct real_pcre16_jit_stack pcre16_jit_stack;
+
+/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain
+a 16 bit wide signed data type. Otherwise it can be a dummy data type since
+pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */
+#ifndef PCRE_UCHAR16
+#define PCRE_UCHAR16 unsigned short
+#endif
+
+#ifndef PCRE_SPTR16
+#define PCRE_SPTR16 const PCRE_UCHAR16 *
+#endif
+
/* When PCRE is compiled as a C++ library, the subject pointer type can be
replaced with a custom type. For conventional use, the public interface is a
const char *. */
@@ -232,8 +316,22 @@
const unsigned char *tables; /* Pointer to character tables */
unsigned long int match_limit_recursion; /* Max recursive calls to match() */
unsigned char **mark; /* For passing back a mark pointer */
+ void *executable_jit; /* Contains a pointer to a compiled jit code */
} pcre_extra;
+/* Same structure as above, but with 16 bit char pointers. */
+
+typedef struct pcre16_extra {
+ unsigned long int flags; /* Bits for which fields are set */
+ void *study_data; /* Opaque data from pcre_study() */
+ unsigned long int match_limit; /* Maximum number of calls to match() */
+ void *callout_data; /* Data passed back in callouts */
+ const unsigned char *tables; /* Pointer to character tables */
+ unsigned long int match_limit_recursion; /* Max recursive calls to match() */
+ PCRE_UCHAR16 **mark; /* For passing back a mark pointer */
+ void *executable_jit; /* Contains a pointer to a compiled jit code */
+} pcre16_extra;
+
/* The structure for passing out data via the pcre_callout_function. We use a
structure so that new fields can be added on the end in future versions,
without changing the API of the function, thereby allowing old clients to work
@@ -254,9 +352,33 @@
/* ------------------- Added for Version 1 -------------------------- */
int pattern_position; /* Offset to next item in the pattern */
int next_item_length; /* Length of next item in the pattern */
+ /* ------------------- Added for Version 2 -------------------------- */
+ const unsigned char *mark; /* Pointer to current mark or NULL */
/* ------------------------------------------------------------------ */
} pcre_callout_block;
+/* Same structure as above, but with 16 bit char pointers. */
+
+typedef struct pcre16_callout_block {
+ int version; /* Identifies version of block */
+ /* ------------------------ Version 0 ------------------------------- */
+ int callout_number; /* Number compiled into pattern */
+ int *offset_vector; /* The offset vector */
+ PCRE_SPTR16 subject; /* The subject being matched */
+ int subject_length; /* The length of the subject */
+ int start_match; /* Offset to start of this match attempt */
+ int current_position; /* Where we currently are in the subject */
+ int capture_top; /* Max current capture */
+ int capture_last; /* Most recently closed capture */
+ void *callout_data; /* Data passed in with the call */
+ /* ------------------- Added for Version 1 -------------------------- */
+ int pattern_position; /* Offset to next item in the pattern */
+ int next_item_length; /* Length of next item in the pattern */
+ /* ------------------- Added for Version 2 -------------------------- */
+ const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */
+ /* ------------------------------------------------------------------ */
+} pcre16_callout_block;
+
/* Indirection for store get and free functions. These can be set to
alternative malloc/free functions if required. Special ones are used in the
non-recursive case for "frames". There is also an optional callout function
@@ -269,47 +391,114 @@
PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
PCRE_EXP_DECL void (*pcre_stack_free)(void *);
PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
+
+PCRE_EXP_DECL void *(*pcre16_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre16_free)(void *);
+PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre16_stack_free)(void *);
+PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *);
#else /* VPCOMPAT */
PCRE_EXP_DECL void *pcre_malloc(size_t);
PCRE_EXP_DECL void pcre_free(void *);
PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
PCRE_EXP_DECL void pcre_stack_free(void *);
PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
+
+PCRE_EXP_DECL void *pcre16_malloc(size_t);
+PCRE_EXP_DECL void pcre16_free(void *);
+PCRE_EXP_DECL void *pcre16_stack_malloc(size_t);
+PCRE_EXP_DECL void pcre16_stack_free(void *);
+PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *);
#endif /* VPCOMPAT */
+/* User defined callback which provides a stack just before the match starts. */
+
+typedef pcre_jit_stack *(*pcre_jit_callback)(void *);
+typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *);
+
/* Exported PCRE functions */
PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
const unsigned char *);
+PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *,
+ const unsigned char *);
PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
int *, const unsigned char *);
+PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **,
+ int *, const unsigned char *);
PCRE_EXP_DECL int pcre_config(int, void *);
+PCRE_EXP_DECL int pcre16_config(int, void *);
PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
int *, int, const char *, char *, int);
-PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *,
- int);
+PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16,
+ int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int);
+PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int,
+ char *, int);
+PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int,
+ PCRE_UCHAR16 *, int);
PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
const char *, int, int, int, int *, int , int *, int);
+PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *,
+ PCRE_SPTR16, int, int, int, int *, int , int *, int);
PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
int, int, int, int *, int);
+PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *,
+ PCRE_SPTR16, int, int, int, int *, int);
PCRE_EXP_DECL void pcre_free_substring(const char *);
+PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16);
PCRE_EXP_DECL void pcre_free_substring_list(const char **);
+PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *);
PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
void *);
+PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int,
+ void *);
PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
int *, int, const char *, const char **);
+PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16,
+ int *, int, PCRE_SPTR16, PCRE_SPTR16 *);
PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
+PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16);
PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
char **, char **);
+PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16,
+ PCRE_UCHAR16 **, PCRE_UCHAR16 **);
PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
const char **);
+PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int,
+ PCRE_SPTR16 *);
PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
const char ***);
-PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *);
+PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int,
+ PCRE_SPTR16 **);
PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
+PCRE_EXP_DECL const unsigned char *pcre16_maketables(void);
PCRE_EXP_DECL int pcre_refcount(pcre *, int);
+PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int);
PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
+PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **);
+PCRE_EXP_DECL void pcre_free_study(pcre_extra *);
+PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *);
PCRE_EXP_DECL const char *pcre_version(void);
+PCRE_EXP_DECL const char *pcre16_version(void);
+
+/* Utility functions for byte order swaps. */
+PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *,
+ const unsigned char *);
+PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *,
+ const unsigned char *);
+PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *,
+ PCRE_SPTR16, int, int *, int);
+
+/* JIT compiler related functions. */
+
+PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int);
+PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int);
+PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *);
+PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *);
+PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *,
+ pcre_jit_callback, void *);
+PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
+ pcre16_jit_callback, void *);
#ifdef __cplusplus
} /* extern "C" */
diff -Nru pcre3-8.12/pcre.h.in pcre3-8.31/pcre.h.in
--- pcre3-8.12/pcre.h.in 2010-11-24 17:38:32.000000000 +0000
+++ pcre3-8.31/pcre.h.in 2012-04-19 16:17:54.000000000 +0000
@@ -5,7 +5,7 @@
/* This is the public header file for the PCRE library, to be #included by
applications that call the PCRE functions.
- Copyright (c) 1997-2010 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -98,28 +98,37 @@
/* Options. Some are compile-time only, some are run-time only, and some are
both, so we keep them all distinct. However, almost all the bits in the options
word are now used. In the long run, we may have to re-use some of the
-compile-time only bits for runtime options, or vice versa. */
+compile-time only bits for runtime options, or vice versa. In the comments
+below, "compile", "exec", and "DFA exec" mean that the option is permitted to
+be set for those functions; "used in" means that an option may be set only for
+compile, but is subsequently referenced in exec and/or DFA exec. Any of the
+compile-time options may be inspected during studying (and therefore JIT
+compiling). */
#define PCRE_CASELESS 0x00000001 /* Compile */
#define PCRE_MULTILINE 0x00000002 /* Compile */
#define PCRE_DOTALL 0x00000004 /* Compile */
#define PCRE_EXTENDED 0x00000008 /* Compile */
#define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */
-#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile */
+#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */
#define PCRE_EXTRA 0x00000040 /* Compile */
#define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */
#define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */
#define PCRE_UNGREEDY 0x00000200 /* Compile */
#define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */
-#define PCRE_UTF8 0x00000800 /* Compile */
+/* The next two are also used in exec and DFA exec */
+#define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */
+#define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */
#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */
-#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile, exec, DFA exec */
+/* The next two are also used in exec and DFA exec */
+#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */
+#define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */
#define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */
#define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */
#define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */
#define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */
#define PCRE_DFA_RESTART 0x00020000 /* DFA exec */
-#define PCRE_FIRSTLINE 0x00040000 /* Compile */
+#define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */
#define PCRE_DUPNAMES 0x00080000 /* Compile */
#define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */
#define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */
@@ -128,41 +137,82 @@
#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */
#define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */
#define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */
-#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile */
+#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */
#define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */
#define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */
#define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */
#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */
-#define PCRE_UCP 0x20000000 /* Compile */
+#define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */
/* Exec-time and get/set-time error codes */
-#define PCRE_ERROR_NOMATCH (-1)
-#define PCRE_ERROR_NULL (-2)
-#define PCRE_ERROR_BADOPTION (-3)
-#define PCRE_ERROR_BADMAGIC (-4)
-#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
-#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
-#define PCRE_ERROR_NOMEMORY (-6)
-#define PCRE_ERROR_NOSUBSTRING (-7)
-#define PCRE_ERROR_MATCHLIMIT (-8)
-#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
-#define PCRE_ERROR_BADUTF8 (-10)
-#define PCRE_ERROR_BADUTF8_OFFSET (-11)
-#define PCRE_ERROR_PARTIAL (-12)
-#define PCRE_ERROR_BADPARTIAL (-13)
-#define PCRE_ERROR_INTERNAL (-14)
-#define PCRE_ERROR_BADCOUNT (-15)
-#define PCRE_ERROR_DFA_UITEM (-16)
-#define PCRE_ERROR_DFA_UCOND (-17)
-#define PCRE_ERROR_DFA_UMLIMIT (-18)
-#define PCRE_ERROR_DFA_WSSIZE (-19)
-#define PCRE_ERROR_DFA_RECURSE (-20)
-#define PCRE_ERROR_RECURSIONLIMIT (-21)
-#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
-#define PCRE_ERROR_BADNEWLINE (-23)
-#define PCRE_ERROR_BADOFFSET (-24)
-#define PCRE_ERROR_SHORTUTF8 (-25)
+#define PCRE_ERROR_NOMATCH (-1)
+#define PCRE_ERROR_NULL (-2)
+#define PCRE_ERROR_BADOPTION (-3)
+#define PCRE_ERROR_BADMAGIC (-4)
+#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
+#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
+#define PCRE_ERROR_NOMEMORY (-6)
+#define PCRE_ERROR_NOSUBSTRING (-7)
+#define PCRE_ERROR_MATCHLIMIT (-8)
+#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
+#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */
+#define PCRE_ERROR_PARTIAL (-12)
+#define PCRE_ERROR_BADPARTIAL (-13)
+#define PCRE_ERROR_INTERNAL (-14)
+#define PCRE_ERROR_BADCOUNT (-15)
+#define PCRE_ERROR_DFA_UITEM (-16)
+#define PCRE_ERROR_DFA_UCOND (-17)
+#define PCRE_ERROR_DFA_UMLIMIT (-18)
+#define PCRE_ERROR_DFA_WSSIZE (-19)
+#define PCRE_ERROR_DFA_RECURSE (-20)
+#define PCRE_ERROR_RECURSIONLIMIT (-21)
+#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
+#define PCRE_ERROR_BADNEWLINE (-23)
+#define PCRE_ERROR_BADOFFSET (-24)
+#define PCRE_ERROR_SHORTUTF8 (-25)
+#define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */
+#define PCRE_ERROR_RECURSELOOP (-26)
+#define PCRE_ERROR_JIT_STACKLIMIT (-27)
+#define PCRE_ERROR_BADMODE (-28)
+#define PCRE_ERROR_BADENDIANNESS (-29)
+#define PCRE_ERROR_DFA_BADRESTART (-30)
+
+/* Specific error codes for UTF-8 validity checks */
+
+#define PCRE_UTF8_ERR0 0
+#define PCRE_UTF8_ERR1 1
+#define PCRE_UTF8_ERR2 2
+#define PCRE_UTF8_ERR3 3
+#define PCRE_UTF8_ERR4 4
+#define PCRE_UTF8_ERR5 5
+#define PCRE_UTF8_ERR6 6
+#define PCRE_UTF8_ERR7 7
+#define PCRE_UTF8_ERR8 8
+#define PCRE_UTF8_ERR9 9
+#define PCRE_UTF8_ERR10 10
+#define PCRE_UTF8_ERR11 11
+#define PCRE_UTF8_ERR12 12
+#define PCRE_UTF8_ERR13 13
+#define PCRE_UTF8_ERR14 14
+#define PCRE_UTF8_ERR15 15
+#define PCRE_UTF8_ERR16 16
+#define PCRE_UTF8_ERR17 17
+#define PCRE_UTF8_ERR18 18
+#define PCRE_UTF8_ERR19 19
+#define PCRE_UTF8_ERR20 20
+#define PCRE_UTF8_ERR21 21
+
+/* Specific error codes for UTF-16 validity checks */
+
+#define PCRE_UTF16_ERR0 0
+#define PCRE_UTF16_ERR1 1
+#define PCRE_UTF16_ERR2 2
+#define PCRE_UTF16_ERR3 3
+#define PCRE_UTF16_ERR4 4
/* Request types for pcre_fullinfo() */
@@ -183,6 +233,9 @@
#define PCRE_INFO_JCHANGED 13
#define PCRE_INFO_HASCRORLF 14
#define PCRE_INFO_MINLENGTH 15
+#define PCRE_INFO_JIT 16
+#define PCRE_INFO_JITSIZE 17
+#define PCRE_INFO_MAXLOOKBEHIND 18
/* Request types for pcre_config(). Do not re-arrange, in order to remain
compatible. */
@@ -196,8 +249,18 @@
#define PCRE_CONFIG_UNICODE_PROPERTIES 6
#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
#define PCRE_CONFIG_BSR 8
+#define PCRE_CONFIG_JIT 9
+#define PCRE_CONFIG_UTF16 10
+#define PCRE_CONFIG_JITTARGET 11
-/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine
+/* Request types for pcre_study(). Do not re-arrange, in order to remain
+compatible. */
+
+#define PCRE_STUDY_JIT_COMPILE 0x0001
+#define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002
+#define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004
+
+/* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine
these bits, just add new ones on the end, in order to remain compatible. */
#define PCRE_EXTRA_STUDY_DATA 0x0001
@@ -206,12 +269,33 @@
#define PCRE_EXTRA_TABLES 0x0008
#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
#define PCRE_EXTRA_MARK 0x0020
+#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040
/* Types */
struct real_pcre; /* declaration; the definition is private */
typedef struct real_pcre pcre;
+struct real_pcre16; /* declaration; the definition is private */
+typedef struct real_pcre16 pcre16;
+
+struct real_pcre_jit_stack; /* declaration; the definition is private */
+typedef struct real_pcre_jit_stack pcre_jit_stack;
+
+struct real_pcre16_jit_stack; /* declaration; the definition is private */
+typedef struct real_pcre16_jit_stack pcre16_jit_stack;
+
+/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain
+a 16 bit wide signed data type. Otherwise it can be a dummy data type since
+pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */
+#ifndef PCRE_UCHAR16
+#define PCRE_UCHAR16 unsigned short
+#endif
+
+#ifndef PCRE_SPTR16
+#define PCRE_SPTR16 const PCRE_UCHAR16 *
+#endif
+
/* When PCRE is compiled as a C++ library, the subject pointer type can be
replaced with a custom type. For conventional use, the public interface is a
const char *. */
@@ -232,8 +316,22 @@
const unsigned char *tables; /* Pointer to character tables */
unsigned long int match_limit_recursion; /* Max recursive calls to match() */
unsigned char **mark; /* For passing back a mark pointer */
+ void *executable_jit; /* Contains a pointer to a compiled jit code */
} pcre_extra;
+/* Same structure as above, but with 16 bit char pointers. */
+
+typedef struct pcre16_extra {
+ unsigned long int flags; /* Bits for which fields are set */
+ void *study_data; /* Opaque data from pcre_study() */
+ unsigned long int match_limit; /* Maximum number of calls to match() */
+ void *callout_data; /* Data passed back in callouts */
+ const unsigned char *tables; /* Pointer to character tables */
+ unsigned long int match_limit_recursion; /* Max recursive calls to match() */
+ PCRE_UCHAR16 **mark; /* For passing back a mark pointer */
+ void *executable_jit; /* Contains a pointer to a compiled jit code */
+} pcre16_extra;
+
/* The structure for passing out data via the pcre_callout_function. We use a
structure so that new fields can be added on the end in future versions,
without changing the API of the function, thereby allowing old clients to work
@@ -254,9 +352,33 @@
/* ------------------- Added for Version 1 -------------------------- */
int pattern_position; /* Offset to next item in the pattern */
int next_item_length; /* Length of next item in the pattern */
+ /* ------------------- Added for Version 2 -------------------------- */
+ const unsigned char *mark; /* Pointer to current mark or NULL */
/* ------------------------------------------------------------------ */
} pcre_callout_block;
+/* Same structure as above, but with 16 bit char pointers. */
+
+typedef struct pcre16_callout_block {
+ int version; /* Identifies version of block */
+ /* ------------------------ Version 0 ------------------------------- */
+ int callout_number; /* Number compiled into pattern */
+ int *offset_vector; /* The offset vector */
+ PCRE_SPTR16 subject; /* The subject being matched */
+ int subject_length; /* The length of the subject */
+ int start_match; /* Offset to start of this match attempt */
+ int current_position; /* Where we currently are in the subject */
+ int capture_top; /* Max current capture */
+ int capture_last; /* Most recently closed capture */
+ void *callout_data; /* Data passed in with the call */
+ /* ------------------- Added for Version 1 -------------------------- */
+ int pattern_position; /* Offset to next item in the pattern */
+ int next_item_length; /* Length of next item in the pattern */
+ /* ------------------- Added for Version 2 -------------------------- */
+ const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */
+ /* ------------------------------------------------------------------ */
+} pcre16_callout_block;
+
/* Indirection for store get and free functions. These can be set to
alternative malloc/free functions if required. Special ones are used in the
non-recursive case for "frames". There is also an optional callout function
@@ -269,47 +391,114 @@
PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
PCRE_EXP_DECL void (*pcre_stack_free)(void *);
PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
+
+PCRE_EXP_DECL void *(*pcre16_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre16_free)(void *);
+PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre16_stack_free)(void *);
+PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *);
#else /* VPCOMPAT */
PCRE_EXP_DECL void *pcre_malloc(size_t);
PCRE_EXP_DECL void pcre_free(void *);
PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
PCRE_EXP_DECL void pcre_stack_free(void *);
PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
+
+PCRE_EXP_DECL void *pcre16_malloc(size_t);
+PCRE_EXP_DECL void pcre16_free(void *);
+PCRE_EXP_DECL void *pcre16_stack_malloc(size_t);
+PCRE_EXP_DECL void pcre16_stack_free(void *);
+PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *);
#endif /* VPCOMPAT */
+/* User defined callback which provides a stack just before the match starts. */
+
+typedef pcre_jit_stack *(*pcre_jit_callback)(void *);
+typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *);
+
/* Exported PCRE functions */
PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
const unsigned char *);
+PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *,
+ const unsigned char *);
PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
int *, const unsigned char *);
+PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **,
+ int *, const unsigned char *);
PCRE_EXP_DECL int pcre_config(int, void *);
+PCRE_EXP_DECL int pcre16_config(int, void *);
PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
int *, int, const char *, char *, int);
-PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *,
- int);
+PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16,
+ int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int);
+PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int,
+ char *, int);
+PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int,
+ PCRE_UCHAR16 *, int);
PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
const char *, int, int, int, int *, int , int *, int);
+PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *,
+ PCRE_SPTR16, int, int, int, int *, int , int *, int);
PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
int, int, int, int *, int);
+PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *,
+ PCRE_SPTR16, int, int, int, int *, int);
PCRE_EXP_DECL void pcre_free_substring(const char *);
+PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16);
PCRE_EXP_DECL void pcre_free_substring_list(const char **);
+PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *);
PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
void *);
+PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int,
+ void *);
PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
int *, int, const char *, const char **);
+PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16,
+ int *, int, PCRE_SPTR16, PCRE_SPTR16 *);
PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
+PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16);
PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
char **, char **);
+PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16,
+ PCRE_UCHAR16 **, PCRE_UCHAR16 **);
PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
const char **);
+PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int,
+ PCRE_SPTR16 *);
PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
const char ***);
-PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *);
+PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int,
+ PCRE_SPTR16 **);
PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
+PCRE_EXP_DECL const unsigned char *pcre16_maketables(void);
PCRE_EXP_DECL int pcre_refcount(pcre *, int);
+PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int);
PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
+PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **);
+PCRE_EXP_DECL void pcre_free_study(pcre_extra *);
+PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *);
PCRE_EXP_DECL const char *pcre_version(void);
+PCRE_EXP_DECL const char *pcre16_version(void);
+
+/* Utility functions for byte order swaps. */
+PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *,
+ const unsigned char *);
+PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *,
+ const unsigned char *);
+PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *,
+ PCRE_SPTR16, int, int *, int);
+
+/* JIT compiler related functions. */
+
+PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int);
+PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int);
+PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *);
+PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *);
+PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *,
+ pcre_jit_callback, void *);
+PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
+ pcre16_jit_callback, void *);
#ifdef __cplusplus
} /* extern "C" */
diff -Nru pcre3-8.12/pcre16_byte_order.c pcre3-8.31/pcre16_byte_order.c
--- pcre3-8.12/pcre16_byte_order.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_byte_order.c 2011-12-28 16:57:51.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_byte_order.c"
+
+/* End of pcre16_byte_order.c */
diff -Nru pcre3-8.12/pcre16_chartables.c pcre3-8.31/pcre16_chartables.c
--- pcre3-8.12/pcre16_chartables.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_chartables.c 2011-12-28 16:57:59.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_chartables.c"
+
+/* End of pcre16_chartables.c */
diff -Nru pcre3-8.12/pcre16_compile.c pcre3-8.31/pcre16_compile.c
--- pcre3-8.12/pcre16_compile.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_compile.c 2011-12-28 16:57:46.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_compile.c"
+
+/* End of pcre16_compile.c */
diff -Nru pcre3-8.12/pcre16_config.c pcre3-8.31/pcre16_config.c
--- pcre3-8.12/pcre16_config.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_config.c 2011-12-28 16:57:51.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_config.c"
+
+/* End of pcre16_config.c */
diff -Nru pcre3-8.12/pcre16_dfa_exec.c pcre3-8.31/pcre16_dfa_exec.c
--- pcre3-8.12/pcre16_dfa_exec.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_dfa_exec.c 2011-12-28 16:57:46.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_dfa_exec.c"
+
+/* End of pcre16_dfa_exec.c */
diff -Nru pcre3-8.12/pcre16_exec.c pcre3-8.31/pcre16_exec.c
--- pcre3-8.12/pcre16_exec.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_exec.c 2011-12-28 16:57:59.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_exec.c"
+
+/* End of pcre16_exec.c */
diff -Nru pcre3-8.12/pcre16_fullinfo.c pcre3-8.31/pcre16_fullinfo.c
--- pcre3-8.12/pcre16_fullinfo.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_fullinfo.c 2011-12-28 16:57:56.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_fullinfo.c"
+
+/* End of pcre16_fullinfo.c */
diff -Nru pcre3-8.12/pcre16_get.c pcre3-8.31/pcre16_get.c
--- pcre3-8.12/pcre16_get.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_get.c 2011-12-28 16:57:50.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_get.c"
+
+/* End of pcre16_get.c */
diff -Nru pcre3-8.12/pcre16_globals.c pcre3-8.31/pcre16_globals.c
--- pcre3-8.12/pcre16_globals.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_globals.c 2011-12-28 16:57:50.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_globals.c"
+
+/* End of pcre16_globals.c */
diff -Nru pcre3-8.12/pcre16_jit_compile.c pcre3-8.31/pcre16_jit_compile.c
--- pcre3-8.12/pcre16_jit_compile.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_jit_compile.c 2011-12-28 16:57:59.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_jit_compile.c"
+
+/* End of pcre16_jit_compile.c */
diff -Nru pcre3-8.12/pcre16_maketables.c pcre3-8.31/pcre16_maketables.c
--- pcre3-8.12/pcre16_maketables.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_maketables.c 2011-12-28 16:57:51.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_maketables.c"
+
+/* End of pcre16_maketables.c */
diff -Nru pcre3-8.12/pcre16_newline.c pcre3-8.31/pcre16_newline.c
--- pcre3-8.12/pcre16_newline.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_newline.c 2011-12-28 16:57:46.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_newline.c"
+
+/* End of pcre16_newline.c */
diff -Nru pcre3-8.12/pcre16_ord2utf16.c pcre3-8.31/pcre16_ord2utf16.c
--- pcre3-8.12/pcre16_ord2utf16.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_ord2utf16.c 2011-12-28 16:57:46.000000000 +0000
@@ -0,0 +1,95 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This file contains a private PCRE function that converts an ordinal
+character value into a UTF16 string. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_internal.h"
+
+/*************************************************
+* Convert character value to UTF-16 *
+*************************************************/
+
+/* This function takes an integer value in the range 0 - 0x10ffff
+and encodes it as a UTF-16 character in 1 to 2 pcre_uchars.
+
+Arguments:
+ cvalue the character value
+ buffer pointer to buffer for result - at least 2 pcre_uchars long
+
+Returns: number of characters placed in the buffer
+*/
+
+int
+PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer)
+{
+#ifdef SUPPORT_UTF
+
+/* Checking invalid cvalue character, encoded as invalid UTF-16 character.
+Should never happen in practice. */
+if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000)
+ cvalue = 0xfffe;
+
+if (cvalue <= 0xffff)
+ {
+ *buffer = (pcre_uchar)cvalue;
+ return 1;
+ }
+
+cvalue -= 0x10000;
+*buffer++ = 0xd800 | (cvalue >> 10);
+*buffer = 0xdc00 | (cvalue & 0x3ff);
+return 2;
+
+#else /* SUPPORT_UTF */
+(void)(cvalue); /* Keep compiler happy; this function won't ever be */
+(void)(buffer); /* called when SUPPORT_UTF is not defined. */
+return 0;
+#endif /* SUPPORT_UTF */
+}
+
+/* End of pcre16_ord2utf16.c */
diff -Nru pcre3-8.12/pcre16_printint.c pcre3-8.31/pcre16_printint.c
--- pcre3-8.12/pcre16_printint.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_printint.c 2011-12-28 16:57:50.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_printint.c"
+
+/* End of pcre16_printint.c */
diff -Nru pcre3-8.12/pcre16_refcount.c pcre3-8.31/pcre16_refcount.c
--- pcre3-8.12/pcre16_refcount.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_refcount.c 2011-12-28 16:57:58.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_refcount.c"
+
+/* End of pcre16_refcount.c */
diff -Nru pcre3-8.12/pcre16_string_utils.c pcre3-8.31/pcre16_string_utils.c
--- pcre3-8.12/pcre16_string_utils.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_string_utils.c 2011-12-28 16:57:59.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_string_utils.c"
+
+/* End of pcre16_string_utils.c */
diff -Nru pcre3-8.12/pcre16_study.c pcre3-8.31/pcre16_study.c
--- pcre3-8.12/pcre16_study.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_study.c 2011-12-28 16:57:51.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_study.c"
+
+/* End of pcre16_study.c */
diff -Nru pcre3-8.12/pcre16_tables.c pcre3-8.31/pcre16_tables.c
--- pcre3-8.12/pcre16_tables.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_tables.c 2011-12-28 16:57:50.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_tables.c"
+
+/* End of pcre16_tables.c */
diff -Nru pcre3-8.12/pcre16_ucd.c pcre3-8.31/pcre16_ucd.c
--- pcre3-8.12/pcre16_ucd.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_ucd.c 2011-12-28 16:57:58.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_ucd.c"
+
+/* End of pcre16_ucd.c */
diff -Nru pcre3-8.12/pcre16_utf16_utils.c pcre3-8.31/pcre16_utf16_utils.c
--- pcre3-8.12/pcre16_utf16_utils.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_utf16_utils.c 2012-01-10 14:05:14.000000000 +0000
@@ -0,0 +1,129 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains a function for converting any UTF-16 character
+strings to host byte order. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_internal.h"
+
+/*************************************************
+* Convert any UTF-16 string to host byte order *
+*************************************************/
+
+/* This function takes an UTF-16 string and converts
+it to host byte order. The length can be explicitly set,
+or automatically detected for zero terminated strings.
+BOMs can be kept or discarded during the conversion.
+Conversion can be done in place (output == input).
+
+Arguments:
+ output the output buffer, its size must be greater
+ or equal than the input string
+ input any UTF-16 string
+ length the number of 16-bit units in the input string
+ can be less than zero for zero terminated strings
+ host_byte_order
+ A non-zero value means the input is in host byte
+ order, which can be dynamically changed by BOMs later.
+ Initially it contains the starting byte order and returns
+ with the last byte order so it can be used for stream
+ processing. It can be NULL, which set the host byte
+ order mode by default.
+ keep_boms for a non-zero value, the BOM (0xfeff) characters
+ are copied as well
+
+Returns: the number of 16-bit units placed into the output buffer,
+ including the zero-terminator
+*/
+
+int
+pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, PCRE_SPTR16 input,
+ int length, int *host_byte_order, int keep_boms)
+{
+#ifdef SUPPORT_UTF
+/* This function converts any UTF-16 string to host byte order and optionally
+removes any Byte Order Marks (BOMS). Returns with the remainig length. */
+int host_bo = host_byte_order != NULL ? *host_byte_order : 1;
+pcre_uchar *optr = (pcre_uchar *)output;
+const pcre_uchar *iptr = (const pcre_uchar *)input;
+const pcre_uchar *end;
+/* The c variable must be unsigned. */
+register pcre_uchar c;
+
+if (length < 0)
+ length = STRLEN_UC(iptr) + 1;
+end = iptr + length;
+
+while (iptr < end)
+ {
+ c = *iptr++;
+ if (c == 0xfeff || c == 0xfffe)
+ {
+ /* Detecting the byte order of the machine is unnecessary, it is
+ enough to know that the UTF-16 string has the same byte order or not. */
+ host_bo = c == 0xfeff;
+ if (keep_boms != 0)
+ *optr++ = 0xfeff;
+ else
+ length--;
+ }
+ else
+ *optr++ = host_bo ? c : ((c >> 8) | (c << 8)); /* Flip bytes if needed. */
+ }
+if (host_byte_order != NULL)
+ *host_byte_order = host_bo;
+
+#else /* SUPPORT_UTF */
+(void)(output); /* Keep picky compilers happy */
+(void)(input);
+(void)(keep_boms);
+#endif /* SUPPORT_UTF */
+return length;
+}
+
+/* End of pcre16_utf16_utils.c */
diff -Nru pcre3-8.12/pcre16_valid_utf16.c pcre3-8.31/pcre16_valid_utf16.c
--- pcre3-8.12/pcre16_valid_utf16.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_valid_utf16.c 2011-12-28 16:57:59.000000000 +0000
@@ -0,0 +1,146 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function for validating UTF-16 character
+strings. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Validate a UTF-16 string *
+*************************************************/
+
+/* This function is called (optionally) at the start of compile or match, to
+check that a supposed UTF-16 string is actually valid. The early check means
+that subsequent code can assume it is dealing with a valid string. The check
+can be turned off for maximum performance, but the consequences of supplying an
+invalid string are then undefined.
+
+From release 8.21 more information about the details of the error are passed
+back in the returned value:
+
+PCRE_UTF16_ERR0 No error
+PCRE_UTF16_ERR1 Missing low surrogate at the end of the string
+PCRE_UTF16_ERR2 Invalid low surrogate
+PCRE_UTF16_ERR3 Isolated low surrogate
+PCRE_UTF16_ERR4 Not allowed character
+
+Arguments:
+ string points to the string
+ length length of string, or -1 if the string is zero-terminated
+ errp pointer to an error position offset variable
+
+Returns: = 0 if the string is a valid UTF-16 string
+ > 0 otherwise, setting the offset of the bad character
+*/
+
+int
+PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset)
+{
+#ifdef SUPPORT_UTF
+register PCRE_PUCHAR p;
+register pcre_uchar c;
+
+if (length < 0)
+ {
+ for (p = string; *p != 0; p++);
+ length = p - string;
+ }
+
+for (p = string; length-- > 0; p++)
+ {
+ c = *p;
+
+ if ((c & 0xf800) != 0xd800)
+ {
+ /* Normal UTF-16 code point. Neither high nor low surrogate. */
+
+ /* This is probably a BOM from a different byte-order.
+ Regardless, the string is rejected. */
+ if (c == 0xfffe)
+ {
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR4;
+ }
+ }
+ else if ((c & 0x0400) == 0)
+ {
+ /* High surrogate. */
+
+ /* Must be a followed by a low surrogate. */
+ if (length == 0)
+ {
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR1;
+ }
+ p++;
+ length--;
+ if ((*p & 0xfc00) != 0xdc00)
+ {
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR2;
+ }
+ }
+ else
+ {
+ /* Isolated low surrogate. Always an error. */
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR3;
+ }
+ }
+
+#else /* SUPPORT_UTF */
+(void)(string); /* Keep picky compilers happy */
+(void)(length);
+#endif /* SUPPORT_UTF */
+
+return PCRE_UTF16_ERR0; /* This indicates success */
+}
+
+/* End of pcre16_valid_utf16.c */
diff -Nru pcre3-8.12/pcre16_version.c pcre3-8.31/pcre16_version.c
--- pcre3-8.12/pcre16_version.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_version.c 2011-12-28 16:57:59.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_version.c"
+
+/* End of pcre16_version.c */
diff -Nru pcre3-8.12/pcre16_xclass.c pcre3-8.31/pcre16_xclass.c
--- pcre3-8.12/pcre16_xclass.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre16_xclass.c 2011-12-28 16:57:51.000000000 +0000
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_xclass.c"
+
+/* End of pcre16_xclass.c */
diff -Nru pcre3-8.12/pcre_byte_order.c pcre3-8.31/pcre_byte_order.c
--- pcre3-8.12/pcre_byte_order.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre_byte_order.c 2012-01-06 12:50:34.000000000 +0000
@@ -0,0 +1,288 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function that tests a compiled pattern to
+see if it was compiled with the opposite endianness. If so, it uses an
+auxiliary local function to flip the appropriate bytes. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Swap byte functions *
+*************************************************/
+
+/* The following functions swap the bytes of a pcre_uint16
+and pcre_uint32 value.
+
+Arguments:
+ value any number
+
+Returns: the byte swapped value
+*/
+
+static pcre_uint32
+swap_uint32(pcre_uint32 value)
+{
+return ((value & 0x000000ff) << 24) |
+ ((value & 0x0000ff00) << 8) |
+ ((value & 0x00ff0000) >> 8) |
+ (value >> 24);
+}
+
+static pcre_uint16
+swap_uint16(pcre_uint16 value)
+{
+return (value >> 8) | (value << 8);
+}
+
+
+/*************************************************
+* Test for a byte-flipped compiled regex *
+*************************************************/
+
+/* This function swaps the bytes of a compiled pattern usually
+loaded form the disk. It also sets the tables pointer, which
+is likely an invalid pointer after reload.
+
+Arguments:
+ argument_re points to the compiled expression
+ extra_data points to extra data or is NULL
+ tables points to the character tables or NULL
+
+Returns: 0 if the swap is successful, negative on error
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re,
+ pcre_extra *extra_data, const unsigned char *tables)
+#else
+PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *argument_re,
+ pcre16_extra *extra_data, const unsigned char *tables)
+#endif
+{
+REAL_PCRE *re = (REAL_PCRE *)argument_re;
+pcre_study_data *study;
+#ifndef COMPILE_PCRE8
+pcre_uchar *ptr;
+int length;
+#ifdef SUPPORT_UTF
+BOOL utf;
+BOOL utf16_char;
+#endif /* SUPPORT_UTF */
+#endif /* !COMPILE_PCRE8 */
+
+if (re == NULL) return PCRE_ERROR_NULL;
+if (re->magic_number == MAGIC_NUMBER)
+ {
+ if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+ re->tables = tables;
+ return 0;
+ }
+
+if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
+if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
+re->magic_number = MAGIC_NUMBER;
+re->size = swap_uint32(re->size);
+re->options = swap_uint32(re->options);
+re->flags = swap_uint16(re->flags);
+re->top_bracket = swap_uint16(re->top_bracket);
+re->top_backref = swap_uint16(re->top_backref);
+re->first_char = swap_uint16(re->first_char);
+re->req_char = swap_uint16(re->req_char);
+re->name_table_offset = swap_uint16(re->name_table_offset);
+re->name_entry_size = swap_uint16(re->name_entry_size);
+re->name_count = swap_uint16(re->name_count);
+re->ref_count = swap_uint16(re->ref_count);
+re->tables = tables;
+
+if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
+ {
+ study = (pcre_study_data *)extra_data->study_data;
+ study->size = swap_uint32(study->size);
+ study->flags = swap_uint32(study->flags);
+ study->minlength = swap_uint32(study->minlength);
+ }
+
+#ifndef COMPILE_PCRE8
+ptr = (pcre_uchar *)re + re->name_table_offset;
+length = re->name_count * re->name_entry_size;
+#ifdef SUPPORT_UTF
+utf = (re->options & PCRE_UTF16) != 0;
+utf16_char = FALSE;
+#endif
+
+while(TRUE)
+ {
+ /* Swap previous characters. */
+ while (length-- > 0)
+ {
+ *ptr = swap_uint16(*ptr);
+ ptr++;
+ }
+#ifdef SUPPORT_UTF
+ if (utf16_char)
+ {
+ if (HAS_EXTRALEN(ptr[-1]))
+ {
+ /* We know that there is only one extra character in UTF-16. */
+ *ptr = swap_uint16(*ptr);
+ ptr++;
+ }
+ }
+ utf16_char = FALSE;
+#endif /* SUPPORT_UTF */
+
+ /* Get next opcode. */
+ length = 0;
+ *ptr = swap_uint16(*ptr);
+ switch (*ptr)
+ {
+ case OP_END:
+ return 0;
+
+#ifdef SUPPORT_UTF
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ if (utf) utf16_char = TRUE;
+#endif
+ /* Fall through. */
+
+ default:
+ length = PRIV(OP_lengths)[*ptr] - 1;
+ break;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ /* Skip the character bit map. */
+ ptr += 32/sizeof(pcre_uchar);
+ length = 0;
+ break;
+
+ case OP_XCLASS:
+ /* Reverse the size of the XCLASS instance. */
+ ptr++;
+ *ptr = swap_uint16(*ptr);
+ if (LINK_SIZE > 1)
+ {
+ /* LINK_SIZE can be 1 or 2 in 16 bit mode. */
+ ptr++;
+ *ptr = swap_uint16(*ptr);
+ }
+ ptr++;
+ length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1);
+ *ptr = swap_uint16(*ptr);
+ if ((*ptr & XCL_MAP) != 0)
+ {
+ /* Skip the character bit map. */
+ ptr += 32/sizeof(pcre_uchar);
+ length -= 32/sizeof(pcre_uchar);
+ }
+ break;
+ }
+ ptr++;
+ }
+/* Control should never reach here in 16 bit mode. */
+#endif /* !COMPILE_PCRE8 */
+
+return 0;
+}
+
+/* End of pcre_byte_order.c */
diff -Nru pcre3-8.12/pcre_chartables.c.dist pcre3-8.31/pcre_chartables.c.dist
--- pcre3-8.12/pcre_chartables.c.dist 2010-06-14 13:54:16.000000000 +0000
+++ pcre3-8.31/pcre_chartables.c.dist 2011-12-28 16:57:59.000000000 +0000
@@ -26,7 +26,7 @@
#include "pcre_internal.h"
-const unsigned char _pcre_default_tables[] = {
+const pcre_uint8 PRIV(default_tables)[] = {
/* This table is a lower casing table. */
diff -Nru pcre3-8.12/pcre_compile.c pcre3-8.31/pcre_compile.c
--- pcre3-8.12/pcre_compile.c 2010-11-24 17:38:32.000000000 +0000
+++ pcre3-8.31/pcre_compile.c 2012-06-20 15:08:50.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2010 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -53,12 +53,16 @@
#include "pcre_internal.h"
-/* When PCRE_DEBUG is defined, we need the pcre_printint() function, which is
-also used by pcretest. PCRE_DEBUG is not defined when building a production
-library. */
+/* When PCRE_DEBUG is defined, we need the pcre(16)_printint() function, which
+is also used by pcretest. PCRE_DEBUG is not defined when building a production
+library. We do not need to select pcre16_printint.c specially, because the
+COMPILE_PCREx macro will already be appropriately set. */
#ifdef PCRE_DEBUG
-#include "pcre_printint.src"
+/* pcre_printint.c should not include any headers */
+#define PCRE_INCLUDED
+#include "pcre_printint.c"
+#undef PCRE_INCLUDED
#endif
@@ -88,15 +92,30 @@
The same workspace is used during the second, actual compile phase for
remembering forward references to groups so that they can be filled in at the
end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE
-is 4 there is plenty of room. */
+is 4 there is plenty of room for most patterns. However, the memory can get
+filled up by repetitions of forward references, for example patterns like
+/(?1){0,1999}(b)/, and one user did hit the limit. The code has been changed so
+that the workspace is expanded using malloc() in this situation. The value
+below is therefore a minimum, and we put a maximum on it for safety. The
+minimum is now also defined in terms of LINK_SIZE so that the use of malloc()
+kicks in at the same number of forward references in all cases. */
-#define COMPILE_WORK_SIZE (4096)
+#define COMPILE_WORK_SIZE (2048*LINK_SIZE)
+#define COMPILE_WORK_SIZE_MAX (100*COMPILE_WORK_SIZE)
/* The overrun tests check for a slightly smaller size so that they detect the
overrun before it actually does run off the end of the data block. */
-#define WORK_SIZE_CHECK (COMPILE_WORK_SIZE - 100)
+#define WORK_SIZE_SAFETY_MARGIN (100)
+/* Private flags added to firstchar and reqchar. */
+
+#define REQ_CASELESS 0x10000000l /* Indicates caselessness */
+#define REQ_VARY 0x20000000l /* Reqchar followed non-literal item */
+
+/* Repeated character flags. */
+
+#define UTF_LENGTH 0x10000000l /* The char contains its length. */
/* Table for handling escaped characters in the range '0'-'z'. Positive returns
are simple data values; negative values are for special things like \d and so
@@ -231,7 +250,7 @@
STRING_graph0 STRING_print0 STRING_punct0 STRING_space0
STRING_word0 STRING_xdigit;
-static const uschar posix_name_lengths[] = {
+static const pcre_uint8 posix_name_lengths[] = {
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
/* Table of class bit maps for each POSIX class. Each class is formed from a
@@ -266,47 +285,101 @@
both positive and negative cases. NULL means no substitute. */
#ifdef SUPPORT_UCP
-static const uschar *substitutes[] = {
- (uschar *)"\\P{Nd}", /* \D */
- (uschar *)"\\p{Nd}", /* \d */
- (uschar *)"\\P{Xsp}", /* \S */ /* NOTE: Xsp is Perl space */
- (uschar *)"\\p{Xsp}", /* \s */
- (uschar *)"\\P{Xwd}", /* \W */
- (uschar *)"\\p{Xwd}" /* \w */
+static const pcre_uchar string_PNd[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pNd[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PXsp[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pXsp[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PXwd[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pXwd[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+
+static const pcre_uchar *substitutes[] = {
+ string_PNd, /* \D */
+ string_pNd, /* \d */
+ string_PXsp, /* \S */ /* NOTE: Xsp is Perl space */
+ string_pXsp, /* \s */
+ string_PXwd, /* \W */
+ string_pXwd /* \w */
};
-static const uschar *posix_substitutes[] = {
- (uschar *)"\\p{L}", /* alpha */
- (uschar *)"\\p{Ll}", /* lower */
- (uschar *)"\\p{Lu}", /* upper */
- (uschar *)"\\p{Xan}", /* alnum */
- NULL, /* ascii */
- (uschar *)"\\h", /* blank */
- NULL, /* cntrl */
- (uschar *)"\\p{Nd}", /* digit */
- NULL, /* graph */
- NULL, /* print */
- NULL, /* punct */
- (uschar *)"\\p{Xps}", /* space */ /* NOTE: Xps is POSIX space */
- (uschar *)"\\p{Xwd}", /* word */
- NULL, /* xdigit */
+static const pcre_uchar string_pL[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pLl[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pLu[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pXan[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_h[] = {
+ CHAR_BACKSLASH, CHAR_h, '\0' };
+static const pcre_uchar string_pXps[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PL[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PLl[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PLu[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PXan[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_H[] = {
+ CHAR_BACKSLASH, CHAR_H, '\0' };
+static const pcre_uchar string_PXps[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+
+static const pcre_uchar *posix_substitutes[] = {
+ string_pL, /* alpha */
+ string_pLl, /* lower */
+ string_pLu, /* upper */
+ string_pXan, /* alnum */
+ NULL, /* ascii */
+ string_h, /* blank */
+ NULL, /* cntrl */
+ string_pNd, /* digit */
+ NULL, /* graph */
+ NULL, /* print */
+ NULL, /* punct */
+ string_pXps, /* space */ /* NOTE: Xps is POSIX space */
+ string_pXwd, /* word */
+ NULL, /* xdigit */
/* Negated cases */
- (uschar *)"\\P{L}", /* ^alpha */
- (uschar *)"\\P{Ll}", /* ^lower */
- (uschar *)"\\P{Lu}", /* ^upper */
- (uschar *)"\\P{Xan}", /* ^alnum */
- NULL, /* ^ascii */
- (uschar *)"\\H", /* ^blank */
- NULL, /* ^cntrl */
- (uschar *)"\\P{Nd}", /* ^digit */
- NULL, /* ^graph */
- NULL, /* ^print */
- NULL, /* ^punct */
- (uschar *)"\\P{Xps}", /* ^space */ /* NOTE: Xps is POSIX space */
- (uschar *)"\\P{Xwd}", /* ^word */
- NULL /* ^xdigit */
+ string_PL, /* ^alpha */
+ string_PLl, /* ^lower */
+ string_PLu, /* ^upper */
+ string_PXan, /* ^alnum */
+ NULL, /* ^ascii */
+ string_H, /* ^blank */
+ NULL, /* ^cntrl */
+ string_PNd, /* ^digit */
+ NULL, /* ^graph */
+ NULL, /* ^print */
+ NULL, /* ^punct */
+ string_PXps, /* ^space */ /* NOTE: Xps is POSIX space */
+ string_PXwd, /* ^word */
+ NULL /* ^xdigit */
};
-#define POSIX_SUBSIZE (sizeof(posix_substitutes)/sizeof(uschar *))
+#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(pcre_uchar *))
#endif
#define STRING(a) # a
@@ -365,7 +438,7 @@
/* 30 */
"unknown POSIX class name\0"
"POSIX collating elements are not supported\0"
- "this version of PCRE is not compiled with PCRE_UTF8 support\0"
+ "this version of PCRE is compiled without UTF support\0"
"spare error\0" /** DEAD **/
"character value in \\x{...} sequence is too large\0"
/* 35 */
@@ -388,12 +461,12 @@
"too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0"
/* 50 */
"repeated subpattern is too long\0" /** DEAD **/
- "octal value is greater than \\377 (not in UTF-8 mode)\0"
+ "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0"
"internal error: overran compiling workspace\0"
"internal error: previously-checked referenced subpattern not found\0"
"DEFINE group contains more than one branch\0"
/* 55 */
- "repeating a DEFINE group is not allowed\0"
+ "repeating a DEFINE group is not allowed\0" /** DEAD **/
"inconsistent NEWLINE options\0"
"\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
"a numbered reference must not be zero\0"
@@ -407,8 +480,18 @@
/* 65 */
"different names for subpatterns of the same number are not allowed\0"
"(*MARK) must have an argument\0"
- "this version of PCRE is not compiled with PCRE_UCP support\0"
+ "this version of PCRE is not compiled with Unicode property support\0"
"\\c must be followed by an ASCII character\0"
+ "\\k is not followed by a braced, angle-bracketed, or quoted name\0"
+ /* 70 */
+ "internal error: unknown opcode in find_fixedlength()\0"
+ "\\N is not supported in a class\0"
+ "too many forward references\0"
+ "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0"
+ "invalid UTF-16 string\0"
+ /* 75 */
+ "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0"
+ "character value in \\u.... sequence is too large\0"
;
/* Table to identify digits and hex digits. This is used when compiling
@@ -427,12 +510,18 @@
Then we can use ctype_digit and ctype_xdigit in the code. */
+/* Using a simple comparison for decimal numbers rather than a memory read
+is much faster, and the resulting code is simpler (the compiler turns it
+into a subtraction and unsigned comparison). */
+
+#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9)
+
#ifndef EBCDIC
/* This is the "normal" case, for ASCII systems, and EBCDIC systems running in
UTF-8 mode. */
-static const unsigned char digitab[] =
+static const pcre_uint8 digitab[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
@@ -471,7 +560,7 @@
/* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */
-static const unsigned char digitab[] =
+static const pcre_uint8 digitab[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
@@ -506,7 +595,7 @@
0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */
0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
-static const unsigned char ebcdic_chartab[] = { /* chartable partial dup */
+static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */
0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */
0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */
@@ -545,7 +634,7 @@
/* Definition to allow mutual recursion */
static BOOL
- compile_regex(int, int, uschar **, const uschar **, int *, BOOL, BOOL, int,
+ compile_regex(int, pcre_uchar **, const pcre_uchar **, int *, BOOL, BOOL, int, int,
int *, int *, branch_chain *, compile_data *, int *);
@@ -577,6 +666,78 @@
/*************************************************
+* Expand the workspace *
+*************************************************/
+
+/* This function is called during the second compiling phase, if the number of
+forward references fills the existing workspace, which is originally a block on
+the stack. A larger block is obtained from malloc() unless the ultimate limit
+has been reached or the increase will be rather small.
+
+Argument: pointer to the compile data block
+Returns: 0 if all went well, else an error number
+*/
+
+static int
+expand_workspace(compile_data *cd)
+{
+pcre_uchar *newspace;
+int newsize = cd->workspace_size * 2;
+
+if (newsize > COMPILE_WORK_SIZE_MAX) newsize = COMPILE_WORK_SIZE_MAX;
+if (cd->workspace_size >= COMPILE_WORK_SIZE_MAX ||
+ newsize - cd->workspace_size < WORK_SIZE_SAFETY_MARGIN)
+ return ERR72;
+
+newspace = (PUBL(malloc))(IN_UCHARS(newsize));
+if (newspace == NULL) return ERR21;
+memcpy(newspace, cd->start_workspace, cd->workspace_size * sizeof(pcre_uchar));
+cd->hwm = (pcre_uchar *)newspace + (cd->hwm - cd->start_workspace);
+if (cd->workspace_size > COMPILE_WORK_SIZE)
+ (PUBL(free))((void *)cd->start_workspace);
+cd->start_workspace = newspace;
+cd->workspace_size = newsize;
+return 0;
+}
+
+
+
+/*************************************************
+* Check for counted repeat *
+*************************************************/
+
+/* This function is called when a '{' is encountered in a place where it might
+start a quantifier. It looks ahead to see if it really is a quantifier or not.
+It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd}
+where the ddds are digits.
+
+Arguments:
+ p pointer to the first char after '{'
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+is_counted_repeat(const pcre_uchar *p)
+{
+if (!IS_DIGIT(*p)) return FALSE;
+p++;
+while (IS_DIGIT(*p)) p++;
+if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
+
+if (*p++ != CHAR_COMMA) return FALSE;
+if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
+
+if (!IS_DIGIT(*p)) return FALSE;
+p++;
+while (IS_DIGIT(*p)) p++;
+
+return (*p == CHAR_RIGHT_CURLY_BRACKET);
+}
+
+
+
+/*************************************************
* Handle escapes *
*************************************************/
@@ -601,12 +762,14 @@
*/
static int
-check_escape(const uschar **ptrptr, int *errorcodeptr, int bracount,
+check_escape(const pcre_uchar **ptrptr, int *errorcodeptr, int bracount,
int options, BOOL isclass)
{
-BOOL utf8 = (options & PCRE_UTF8) != 0;
-const uschar *ptr = *ptrptr + 1;
-int c, i;
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+BOOL utf = (options & PCRE_UTF8) != 0;
+const pcre_uchar *ptr = *ptrptr + 1;
+pcre_int32 c;
+int i;
GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */
ptr--; /* Set pointer back to the last byte */
@@ -620,11 +783,13 @@
Otherwise further processing may be required. */
#ifndef EBCDIC /* ASCII/UTF-8 coding */
-else if (c < CHAR_0 || c > CHAR_z) {} /* Not alphanumeric */
+/* Not alphanumeric */
+else if (c < CHAR_0 || c > CHAR_z) {}
else if ((i = escapes[c - CHAR_0]) != 0) c = i;
#else /* EBCDIC coding */
-else if (c < 'a' || (ebcdic_chartab[c] & 0x0E) == 0) {} /* Not alphanumeric */
+/* Not alphanumeric */
+else if (c < 'a' || (!MAX_255(c) || (ebcdic_chartab[c] & 0x0E) == 0)) {}
else if ((i = escapes[c - 0x48]) != 0) c = i;
#endif
@@ -632,7 +797,7 @@
else
{
- const uschar *oldptr;
+ const pcre_uchar *oldptr;
BOOL braced, negated;
switch (c)
@@ -642,12 +807,56 @@
case CHAR_l:
case CHAR_L:
+ *errorcodeptr = ERR37;
+ break;
+
case CHAR_u:
+ if ((options & PCRE_JAVASCRIPT_COMPAT) != 0)
+ {
+ /* In JavaScript, \u must be followed by four hexadecimal numbers.
+ Otherwise it is a lowercase u letter. */
+ if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0
+ && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0
+ && MAX_255(ptr[3]) && (digitab[ptr[3]] & ctype_xdigit) != 0
+ && MAX_255(ptr[4]) && (digitab[ptr[4]] & ctype_xdigit) != 0)
+ {
+ c = 0;
+ for (i = 0; i < 4; ++i)
+ {
+ register int cc = *(++ptr);
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else /* EBCDIC coding */
+ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+ }
+
+#ifdef COMPILE_PCRE8
+ if (c > (utf ? 0x10ffff : 0xff))
+#else
+#ifdef COMPILE_PCRE16
+ if (c > (utf ? 0x10ffff : 0xffff))
+#endif
+#endif
+ {
+ *errorcodeptr = ERR76;
+ }
+ else if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
+ }
+ }
+ else
+ *errorcodeptr = ERR37;
+ break;
+
case CHAR_U:
- *errorcodeptr = ERR37;
+ /* In JavaScript, \U is an uppercase U letter. */
+ if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) *errorcodeptr = ERR37;
break;
- /* \g must be followed by one of a number of specific things:
+ /* In a character class, \g is just a literal "g". Outside a character
+ class, \g must be followed by one of a number of specific things:
(1) A number, either plain or braced. If positive, it is an absolute
backreference. If negative, it is a relative backreference. This is a Perl
@@ -664,6 +873,7 @@
the -ESC_g code (cf \k). */
case CHAR_g:
+ if (isclass) break;
if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE)
{
c = -ESC_g;
@@ -674,9 +884,9 @@
if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
{
- const uschar *p;
+ const pcre_uchar *p;
for (p = ptr+2; *p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET; p++)
- if (*p != CHAR_MINUS && (digitab[*p] & ctype_digit) == 0) break;
+ if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break;
if (*p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET)
{
c = -ESC_k;
@@ -694,12 +904,21 @@
}
else negated = FALSE;
+ /* The integer range is limited by the machine's int representation. */
c = 0;
- while ((digitab[ptr[1]] & ctype_digit) != 0)
+ while (IS_DIGIT(ptr[1]))
+ {
+ if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */
+ {
+ c = -1;
+ break;
+ }
c = c * 10 + *(++ptr) - CHAR_0;
-
- if (c < 0) /* Integer overflow */
+ }
+ if (((unsigned int)c) > INT_MAX) /* Integer overflow */
{
+ while (IS_DIGIT(ptr[1]))
+ ptr++;
*errorcodeptr = ERR61;
break;
}
@@ -747,11 +966,21 @@
if (!isclass)
{
oldptr = ptr;
+ /* The integer range is limited by the machine's int representation. */
c -= CHAR_0;
- while ((digitab[ptr[1]] & ctype_digit) != 0)
+ while (IS_DIGIT(ptr[1]))
+ {
+ if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */
+ {
+ c = -1;
+ break;
+ }
c = c * 10 + *(++ptr) - CHAR_0;
- if (c < 0) /* Integer overflow */
+ }
+ if (((unsigned int)c) > INT_MAX) /* Integer overflow */
{
+ while (IS_DIGIT(ptr[1]))
+ ptr++;
*errorcodeptr = ERR61;
break;
}
@@ -777,32 +1006,55 @@
/* \0 always starts an octal number, but we may drop through to here with a
larger first octal digit. The original code used just to take the least
significant 8 bits of octal numbers (I think this is what early Perls used
- to do). Nowadays we allow for larger numbers in UTF-8 mode, but no more
- than 3 octal digits. */
+ to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode,
+ but no more than 3 octal digits. */
case CHAR_0:
c -= CHAR_0;
while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7)
c = c * 8 + *(++ptr) - CHAR_0;
- if (!utf8 && c > 255) *errorcodeptr = ERR51;
+#ifdef COMPILE_PCRE8
+ if (!utf && c > 0xff) *errorcodeptr = ERR51;
+#endif
break;
/* \x is complicated. \x{ddd} is a character number which can be greater
- than 0xff in utf8 mode, but only if the ddd are hex digits. If not, { is
- treated as a data character. */
+ than 0xff in utf or non-8bit mode, but only if the ddd are hex digits.
+ If not, { is treated as a data character. */
case CHAR_x:
+ if ((options & PCRE_JAVASCRIPT_COMPAT) != 0)
+ {
+ /* In JavaScript, \x must be followed by two hexadecimal numbers.
+ Otherwise it is a lowercase x letter. */
+ if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0
+ && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0)
+ {
+ c = 0;
+ for (i = 0; i < 2; ++i)
+ {
+ register int cc = *(++ptr);
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else /* EBCDIC coding */
+ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+ }
+ }
+ break;
+ }
+
if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
{
- const uschar *pt = ptr + 2;
- int count = 0;
+ const pcre_uchar *pt = ptr + 2;
c = 0;
- while ((digitab[*pt] & ctype_xdigit) != 0)
+ while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0)
{
register int cc = *pt++;
if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
- count++;
#ifndef EBCDIC /* ASCII/UTF-8 coding */
if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
@@ -811,11 +1063,25 @@
if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
#endif
+
+#ifdef COMPILE_PCRE8
+ if (c > (utf ? 0x10ffff : 0xff)) { c = -1; break; }
+#else
+#ifdef COMPILE_PCRE16
+ if (c > (utf ? 0x10ffff : 0xffff)) { c = -1; break; }
+#endif
+#endif
+ }
+
+ if (c < 0)
+ {
+ while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++;
+ *errorcodeptr = ERR34;
}
if (*pt == CHAR_RIGHT_CURLY_BRACKET)
{
- if (c < 0 || count > (utf8? 8 : 2)) *errorcodeptr = ERR34;
+ if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
ptr = pt;
break;
}
@@ -827,7 +1093,7 @@
/* Read just a single-byte hex-defined char */
c = 0;
- while (i++ < 2 && (digitab[ptr[1]] & ctype_xdigit) != 0)
+ while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0)
{
int cc; /* Some compilers don't like */
cc = *(++ptr); /* ++ in initializers */
@@ -885,9 +1151,11 @@
}
/* Perl supports \N{name} for character names, as well as plain \N for "not
-newline". PCRE does not support \N{name}. */
+newline". PCRE does not support \N{name}. However, it does support
+quantification such as \N{2,3}. */
-if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET)
+if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET &&
+ !is_counted_repeat(ptr+2))
*errorcodeptr = ERR37;
/* If PCRE_UCP is set, we change the values for \d etc. */
@@ -923,11 +1191,11 @@
*/
static int
-get_ucp(const uschar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr)
+get_ucp(const pcre_uchar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr)
{
int c, i, bot, top;
-const uschar *ptr = *ptrptr;
-char name[32];
+const pcre_uchar *ptr = *ptrptr;
+pcre_uchar name[32];
c = *(++ptr);
if (c == 0) goto ERROR_RETURN;
@@ -944,7 +1212,7 @@
*negptr = TRUE;
ptr++;
}
- for (i = 0; i < (int)sizeof(name) - 1; i++)
+ for (i = 0; i < (int)(sizeof(name) / sizeof(pcre_uchar)) - 1; i++)
{
c = *(++ptr);
if (c == 0) goto ERROR_RETURN;
@@ -968,16 +1236,16 @@
/* Search for a recognized property name using binary chop */
bot = 0;
-top = _pcre_utt_size;
+top = PRIV(utt_size);
while (bot < top)
{
i = (bot + top) >> 1;
- c = strcmp(name, _pcre_utt_names + _pcre_utt[i].name_offset);
+ c = STRCMP_UC_C8(name, PRIV(utt_names) + PRIV(utt)[i].name_offset);
if (c == 0)
{
- *dptr = _pcre_utt[i].value;
- return _pcre_utt[i].type;
+ *dptr = PRIV(utt)[i].value;
+ return PRIV(utt)[i].type;
}
if (c > 0) bot = i + 1; else top = i;
}
@@ -997,39 +1265,6 @@
/*************************************************
-* Check for counted repeat *
-*************************************************/
-
-/* This function is called when a '{' is encountered in a place where it might
-start a quantifier. It looks ahead to see if it really is a quantifier or not.
-It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd}
-where the ddds are digits.
-
-Arguments:
- p pointer to the first char after '{'
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_counted_repeat(const uschar *p)
-{
-if ((digitab[*p++] & ctype_digit) == 0) return FALSE;
-while ((digitab[*p] & ctype_digit) != 0) p++;
-if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
-
-if (*p++ != CHAR_COMMA) return FALSE;
-if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
-
-if ((digitab[*p++] & ctype_digit) == 0) return FALSE;
-while ((digitab[*p] & ctype_digit) != 0) p++;
-
-return (*p == CHAR_RIGHT_CURLY_BRACKET);
-}
-
-
-
-/*************************************************
* Read repeat counts *
*************************************************/
@@ -1048,8 +1283,8 @@
current ptr on error, with errorcodeptr set non-zero
*/
-static const uschar *
-read_repeat_counts(const uschar *p, int *minp, int *maxp, int *errorcodeptr)
+static const pcre_uchar *
+read_repeat_counts(const pcre_uchar *p, int *minp, int *maxp, int *errorcodeptr)
{
int min = 0;
int max = -1;
@@ -1057,7 +1292,7 @@
/* Read the minimum value and do a paranoid check: a negative value indicates
an integer overflow. */
-while ((digitab[*p] & ctype_digit) != 0) min = min * 10 + *p++ - CHAR_0;
+while (IS_DIGIT(*p)) min = min * 10 + *p++ - CHAR_0;
if (min < 0 || min > 65535)
{
*errorcodeptr = ERR5;
@@ -1072,7 +1307,7 @@
if (*(++p) != CHAR_RIGHT_CURLY_BRACKET)
{
max = 0;
- while((digitab[*p] & ctype_digit) != 0) max = max * 10 + *p++ - CHAR_0;
+ while(IS_DIGIT(*p)) max = max * 10 + *p++ - CHAR_0;
if (max < 0 || max > 65535)
{
*errorcodeptr = ERR5;
@@ -1127,17 +1362,17 @@
name name to seek, or NULL if seeking a numbered subpattern
lorn name length, or subpattern number if name is NULL
xmode TRUE if we are in /x mode
- utf8 TRUE if we are in UTF-8 mode
+ utf TRUE if we are in UTF-8 / UTF-16 mode
count pointer to the current capturing subpattern number (updated)
Returns: the number of the named subpattern, or -1 if not found
*/
static int
-find_parens_sub(uschar **ptrptr, compile_data *cd, const uschar *name, int lorn,
- BOOL xmode, BOOL utf8, int *count)
+find_parens_sub(pcre_uchar **ptrptr, compile_data *cd, const pcre_uchar *name, int lorn,
+ BOOL xmode, BOOL utf, int *count)
{
-uschar *ptr = *ptrptr;
+pcre_uchar *ptr = *ptrptr;
int start_count = *count;
int hwm_count = start_count;
BOOL dup_parens = FALSE;
@@ -1204,7 +1439,7 @@
ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE)
{
int term;
- const uschar *thisname;
+ const pcre_uchar *thisname;
*count += 1;
if (name == NULL && *count == lorn) return *count;
term = *ptr++;
@@ -1212,7 +1447,7 @@
thisname = ptr;
while (*ptr != term) ptr++;
if (name != NULL && lorn == ptr - thisname &&
- strncmp((const char *)name, (const char *)thisname, lorn) == 0)
+ STRNCMP_UC_UC(name, thisname, lorn) == 0)
return *count;
term++;
}
@@ -1255,7 +1490,7 @@
{
if (ptr[2] == CHAR_E)
ptr+= 2;
- else if (strncmp((const char *)ptr+2,
+ else if (STRNCMP_UC_C8(ptr + 2,
STR_Q STR_BACKSLASH STR_E, 3) == 0)
ptr += 4;
else
@@ -1303,8 +1538,8 @@
{
if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
ptr++;
-#ifdef SUPPORT_UTF8
- if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
#endif
}
if (*ptr == 0) goto FAIL_EXIT;
@@ -1315,7 +1550,7 @@
if (*ptr == CHAR_LEFT_PARENTHESIS)
{
- int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf8, count);
+ int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count);
if (rc > 0) return rc;
if (*ptr == 0) goto FAIL_EXIT;
}
@@ -1361,16 +1596,16 @@
name name to seek, or NULL if seeking a numbered subpattern
lorn name length, or subpattern number if name is NULL
xmode TRUE if we are in /x mode
- utf8 TRUE if we are in UTF-8 mode
+ utf TRUE if we are in UTF-8 / UTF-16 mode
Returns: the number of the found subpattern, or -1 if not found
*/
static int
-find_parens(compile_data *cd, const uschar *name, int lorn, BOOL xmode,
- BOOL utf8)
+find_parens(compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode,
+ BOOL utf)
{
-uschar *ptr = (uschar *)cd->start_pattern;
+pcre_uchar *ptr = (pcre_uchar *)cd->start_pattern;
int count = 0;
int rc;
@@ -1381,7 +1616,7 @@
for (;;)
{
- rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf8, &count);
+ rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count);
if (rc > 0 || *ptr++ == 0) break;
}
@@ -1397,40 +1632,30 @@
/* This is called by several functions that scan a compiled expression looking
for a fixed first character, or an anchoring op code etc. It skips over things
-that do not influence this. For some calls, a change of option is important.
-For some calls, it makes sense to skip negative forward and all backward
-assertions, and also the \b assertion; for others it does not.
+that do not influence this. For some calls, it makes sense to skip negative
+forward and all backward assertions, and also the \b assertion; for others it
+does not.
Arguments:
code pointer to the start of the group
- options pointer to external options
- optbit the option bit whose changing is significant, or
- zero if none are
skipassert TRUE if certain assertions are to be skipped
Returns: pointer to the first significant opcode
*/
-static const uschar*
-first_significant_code(const uschar *code, int *options, int optbit,
- BOOL skipassert)
+static const pcre_uchar*
+first_significant_code(const pcre_uchar *code, BOOL skipassert)
{
for (;;)
{
switch ((int)*code)
{
- case OP_OPT:
- if (optbit > 0 && ((int)code[1] & optbit) != (*options & optbit))
- *options = (int)code[1];
- code += 2;
- break;
-
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
if (!skipassert) return code;
do code += GET(code, 1); while (*code == OP_ALT);
- code += _pcre_OP_lengths[*code];
+ code += PRIV(OP_lengths)[*code];
break;
case OP_WORD_BOUNDARY:
@@ -1444,7 +1669,7 @@
case OP_RREF:
case OP_NRREF:
case OP_DEF:
- code += _pcre_OP_lengths[*code];
+ code += PRIV(OP_lengths)[*code];
break;
default:
@@ -1474,23 +1699,24 @@
Arguments:
code points to the start of the pattern (the bracket)
- options the compiling options
+ utf TRUE in UTF-8 / UTF-16 mode
atend TRUE if called when the pattern is complete
cd the "compile data" structure
Returns: the fixed length,
or -1 if there is no fixed length,
- or -2 if \C was encountered
+ or -2 if \C was encountered (in UTF-8 mode only)
or -3 if an OP_RECURSE item was encountered and atend is FALSE
+ or -4 if an unknown opcode was encountered (internal error)
*/
static int
-find_fixedlength(uschar *code, int options, BOOL atend, compile_data *cd)
+find_fixedlength(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd)
{
int length = -1;
register int branchlength = 0;
-register uschar *cc = code + 1 + LINK_SIZE;
+register pcre_uchar *cc = code + 1 + LINK_SIZE;
/* Scan along the opcodes for this branch. If we get to the end of the
branch, check the length against that of the other branches. */
@@ -1498,30 +1724,39 @@
for (;;)
{
int d;
- uschar *ce, *cs;
+ pcre_uchar *ce, *cs;
register int op = *cc;
+
switch (op)
{
+ /* We only need to continue for OP_CBRA (normal capturing bracket) and
+ OP_BRA (normal non-capturing bracket) because the other variants of these
+ opcodes are all concerned with unlimited repeated groups, which of course
+ are not of fixed length. */
+
case OP_CBRA:
case OP_BRA:
case OP_ONCE:
+ case OP_ONCE_NC:
case OP_COND:
- d = find_fixedlength(cc + ((op == OP_CBRA)? 2:0), options, atend, cd);
+ d = find_fixedlength(cc + ((op == OP_CBRA)? IMM2_SIZE : 0), utf, atend, cd);
if (d < 0) return d;
branchlength += d;
do cc += GET(cc, 1); while (*cc == OP_ALT);
cc += 1 + LINK_SIZE;
break;
- /* Reached end of a branch; if it's a ket it is the end of a nested
- call. If it's ALT it is an alternation in a nested call. If it is
- END it's the end of the outer call. All can be handled by the same code. */
+ /* Reached end of a branch; if it's a ket it is the end of a nested call.
+ If it's ALT it is an alternation in a nested call. An ACCEPT is effectively
+ an ALT. If it is END it's the end of the outer call. All can be handled by
+ the same code. Note that we must not include the OP_KETRxxx opcodes here,
+ because they all imply an unlimited repeat. */
case OP_ALT:
case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
case OP_END:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
if (length < 0) length = branchlength;
else if (length != branchlength) return -1;
if (*cc != OP_ALT) return length;
@@ -1535,10 +1770,10 @@
case OP_RECURSE:
if (!atend) return -3;
- cs = ce = (uschar *)cd->start_code + GET(cc, 1); /* Start subpattern */
- do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */
- if (cc > cs && cc < ce) return -1; /* Recursion */
- d = find_fixedlength(cs + 2, options, atend, cd);
+ cs = ce = (pcre_uchar *)cd->start_code + GET(cc, 1); /* Start subpattern */
+ do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */
+ if (cc > cs && cc < ce) return -1; /* Recursion */
+ d = find_fixedlength(cs + IMM2_SIZE, utf, atend, cd);
if (d < 0) return d;
branchlength += d;
cc += 1 + LINK_SIZE;
@@ -1551,40 +1786,55 @@
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
do cc += GET(cc, 1); while (*cc == OP_ALT);
- /* Fall through */
+ cc += PRIV(OP_lengths)[*cc];
+ break;
/* Skip over things that don't match chars */
- case OP_REVERSE:
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ cc += cc[1] + PRIV(OP_lengths)[*cc];
+ break;
+
+ case OP_CALLOUT:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_CLOSE:
+ case OP_COMMIT:
case OP_CREF:
- case OP_NCREF:
- case OP_RREF:
- case OP_NRREF:
case OP_DEF:
- case OP_OPT:
- case OP_CALLOUT:
- case OP_SOD:
- case OP_SOM:
- case OP_SET_SOM:
+ case OP_DOLL:
+ case OP_DOLLM:
case OP_EOD:
case OP_EODN:
- case OP_CIRC:
- case OP_DOLL:
+ case OP_FAIL:
+ case OP_NCREF:
+ case OP_NRREF:
case OP_NOT_WORD_BOUNDARY:
+ case OP_PRUNE:
+ case OP_REVERSE:
+ case OP_RREF:
+ case OP_SET_SOM:
+ case OP_SKIP:
+ case OP_SOD:
+ case OP_SOM:
+ case OP_THEN:
case OP_WORD_BOUNDARY:
- cc += _pcre_OP_lengths[*cc];
+ cc += PRIV(OP_lengths)[*cc];
break;
/* Handle literal characters */
case OP_CHAR:
- case OP_CHARNC:
+ case OP_CHARI:
case OP_NOT:
+ case OP_NOTI:
branchlength++;
cc += 2;
-#ifdef SUPPORT_UTF8
- if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0)
- cc += _pcre_utf8_table4[cc[-1] & 0x3f];
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
#endif
break;
@@ -1592,18 +1842,20 @@
need to skip over a multibyte character in UTF8 mode. */
case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
branchlength += GET2(cc,1);
- cc += 4;
-#ifdef SUPPORT_UTF8
- if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0)
- cc += _pcre_utf8_table4[cc[-1] & 0x3f];
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
#endif
break;
case OP_TYPEEXACT:
branchlength += GET2(cc,1);
- if (cc[3] == OP_PROP || cc[3] == OP_NOTPROP) cc += 2;
- cc += 4;
+ if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;
+ cc += 1 + IMM2_SIZE + 1;
break;
/* Handle single-char matchers */
@@ -1613,6 +1865,10 @@
cc += 2;
/* Fall through */
+ case OP_HSPACE:
+ case OP_VSPACE:
+ case OP_NOT_HSPACE:
+ case OP_NOT_VSPACE:
case OP_NOT_DIGIT:
case OP_DIGIT:
case OP_NOT_WHITESPACE:
@@ -1625,25 +1881,28 @@
cc++;
break;
- /* The single-byte matcher isn't allowed */
+ /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode;
+ otherwise \C is coded as OP_ALLANY. */
case OP_ANYBYTE:
return -2;
/* Check a class for variable quantification */
-#ifdef SUPPORT_UTF8
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
case OP_XCLASS:
- cc += GET(cc, 1) - 33;
+ cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS];
/* Fall through */
#endif
case OP_CLASS:
case OP_NCLASS:
- cc += 33;
+ cc += PRIV(OP_lengths)[OP_CLASS];
switch (*cc)
{
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
case OP_CRSTAR:
case OP_CRMINSTAR:
case OP_CRQUERY:
@@ -1652,9 +1911,9 @@
case OP_CRRANGE:
case OP_CRMINRANGE:
- if (GET2(cc,1) != GET2(cc,3)) return -1;
+ if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1;
branchlength += GET2(cc,1);
- cc += 5;
+ cc += 1 + 2 * IMM2_SIZE;
break;
default:
@@ -1664,8 +1923,91 @@
/* Anything else is variable length */
- default:
+ case OP_ANYNL:
+ case OP_BRAMINZERO:
+ case OP_BRAPOS:
+ case OP_BRAPOSZERO:
+ case OP_BRAZERO:
+ case OP_CBRAPOS:
+ case OP_EXTUNI:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_REF:
+ case OP_REFI:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ case OP_SCOND:
+ case OP_SKIPZERO:
+ case OP_STAR:
+ case OP_STARI:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPLUS:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSUPTO:
+ case OP_TYPEQUERY:
+ case OP_TYPESTAR:
+ case OP_TYPEUPTO:
+ case OP_UPTO:
+ case OP_UPTOI:
return -1;
+
+ /* Catch unrecognized opcodes so that when new ones are added they
+ are not forgotten, as has happened in the past. */
+
+ default:
+ return -4;
}
}
/* Control never gets here */
@@ -1686,18 +2028,19 @@
Arguments:
code points to start of expression
- utf8 TRUE in UTF-8 mode
+ utf TRUE in UTF-8 / UTF-16 mode
number the required bracket number or negative to find a lookbehind
Returns: pointer to the opcode for the bracket, or NULL if not found
*/
-const uschar *
-_pcre_find_bracket(const uschar *code, BOOL utf8, int number)
+const pcre_uchar *
+PRIV(find_bracket)(const pcre_uchar *code, BOOL utf, int number)
{
for (;;)
{
register int c = *code;
+
if (c == OP_END) return NULL;
/* XCLASS is used for classes that cannot be represented just by a bit
@@ -1710,17 +2053,18 @@
else if (c == OP_REVERSE)
{
- if (number < 0) return (uschar *)code;
- code += _pcre_OP_lengths[c];
+ if (number < 0) return (pcre_uchar *)code;
+ code += PRIV(OP_lengths)[c];
}
/* Handle capturing bracket */
- else if (c == OP_CBRA)
+ else if (c == OP_CBRA || c == OP_SCBRA ||
+ c == OP_CBRAPOS || c == OP_SCBRAPOS)
{
int n = GET2(code, 1+LINK_SIZE);
- if (n == number) return (uschar *)code;
- code += _pcre_OP_lengths[c];
+ if (n == number) return (pcre_uchar *)code;
+ code += PRIV(OP_lengths)[c];
}
/* Otherwise, we can get the item's length from the table, except that for
@@ -1748,7 +2092,8 @@
case OP_TYPEMINUPTO:
case OP_TYPEEXACT:
case OP_TYPEPOSUPTO:
- if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
+ if (code[1 + IMM2_SIZE] == OP_PROP
+ || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
break;
case OP_MARK:
@@ -1758,41 +2103,54 @@
break;
case OP_THEN_ARG:
- code += code[1+LINK_SIZE];
+ code += code[1];
break;
}
/* Add in the fixed length from the table */
- code += _pcre_OP_lengths[c];
+ code += PRIV(OP_lengths)[c];
/* In UTF-8 mode, opcodes that are followed by a character may be followed by
a multi-byte character. The length in the table is a minimum, so we have to
arrange to skip the extra bytes. */
-#ifdef SUPPORT_UTF8
- if (utf8) switch(c)
+#ifdef SUPPORT_UTF
+ if (utf) switch(c)
{
case OP_CHAR:
- case OP_CHARNC:
+ case OP_CHARI:
case OP_EXACT:
+ case OP_EXACTI:
case OP_UPTO:
+ case OP_UPTOI:
case OP_MINUPTO:
+ case OP_MINUPTOI:
case OP_POSUPTO:
+ case OP_POSUPTOI:
case OP_STAR:
+ case OP_STARI:
case OP_MINSTAR:
+ case OP_MINSTARI:
case OP_POSSTAR:
+ case OP_POSSTARI:
case OP_PLUS:
+ case OP_PLUSI:
case OP_MINPLUS:
+ case OP_MINPLUSI:
case OP_POSPLUS:
+ case OP_POSPLUSI:
case OP_QUERY:
+ case OP_QUERYI:
case OP_MINQUERY:
+ case OP_MINQUERYI:
case OP_POSQUERY:
- if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];
+ case OP_POSQUERYI:
+ if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
break;
}
#else
- (void)(utf8); /* Keep compiler happy by referencing function argument */
+ (void)(utf); /* Keep compiler happy by referencing function argument */
#endif
}
}
@@ -1809,13 +2167,13 @@
Arguments:
code points to start of expression
- utf8 TRUE in UTF-8 mode
+ utf TRUE in UTF-8 / UTF-16 mode
Returns: pointer to the opcode for OP_RECURSE, or NULL if not found
*/
-static const uschar *
-find_recurse(const uschar *code, BOOL utf8)
+static const pcre_uchar *
+find_recurse(const pcre_uchar *code, BOOL utf)
{
for (;;)
{
@@ -1854,7 +2212,8 @@
case OP_TYPEUPTO:
case OP_TYPEMINUPTO:
case OP_TYPEEXACT:
- if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
+ if (code[1 + IMM2_SIZE] == OP_PROP
+ || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
break;
case OP_MARK:
@@ -1864,41 +2223,82 @@
break;
case OP_THEN_ARG:
- code += code[1+LINK_SIZE];
+ code += code[1];
break;
}
/* Add in the fixed length from the table */
- code += _pcre_OP_lengths[c];
+ code += PRIV(OP_lengths)[c];
/* In UTF-8 mode, opcodes that are followed by a character may be followed
by a multi-byte character. The length in the table is a minimum, so we have
to arrange to skip the extra bytes. */
-#ifdef SUPPORT_UTF8
- if (utf8) switch(c)
+#ifdef SUPPORT_UTF
+ if (utf) switch(c)
{
case OP_CHAR:
- case OP_CHARNC:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
case OP_UPTO:
+ case OP_UPTOI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
case OP_STAR:
+ case OP_STARI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
case OP_PLUS:
+ case OP_PLUSI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
case OP_QUERY:
+ case OP_QUERYI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
case OP_POSQUERY:
- if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];
+ case OP_POSQUERYI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
break;
}
#else
- (void)(utf8); /* Keep compiler happy by referencing function argument */
+ (void)(utf); /* Keep compiler happy by referencing function argument */
#endif
}
}
@@ -1921,22 +2321,22 @@
Arguments:
code points to start of search
endcode points to where to stop
- utf8 TRUE if in UTF8 mode
+ utf TRUE if in UTF-8 / UTF-16 mode
cd contains pointers to tables etc.
Returns: TRUE if what is matched could be empty
*/
static BOOL
-could_be_empty_branch(const uschar *code, const uschar *endcode, BOOL utf8,
- compile_data *cd)
+could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode,
+ BOOL utf, compile_data *cd)
{
register int c;
-for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE);
+for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
code < endcode;
- code = first_significant_code(code + _pcre_OP_lengths[c], NULL, 0, TRUE))
+ code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE))
{
- const uschar *ccode;
+ const pcre_uchar *ccode;
c = *code;
@@ -1950,27 +2350,34 @@
continue;
}
- /* Groups with zero repeats can of course be empty; skip them. */
-
- if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO)
- {
- code += _pcre_OP_lengths[c];
- do code += GET(code, 1); while (*code == OP_ALT);
- c = *code;
- continue;
- }
-
/* For a recursion/subroutine call, if its end has been reached, which
- implies a subroutine call, we can scan it. */
+ implies a backward reference subroutine call, we can scan it. If it's a
+ forward reference subroutine call, we can't. To detect forward reference
+ we have to scan up the list that is kept in the workspace. This function is
+ called only when doing the real compile, not during the pre-compile that
+ measures the size of the compiled pattern. */
if (c == OP_RECURSE)
{
- BOOL empty_branch = FALSE;
- const uschar *scode = cd->start_code + GET(code, 1);
+ const pcre_uchar *scode;
+ BOOL empty_branch;
+
+ /* Test for forward reference */
+
+ for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE)
+ if (GET(scode, 0) == code + 1 - cd->start_code) return TRUE;
+
+ /* Not a forward reference, test for completed backward reference */
+
+ empty_branch = FALSE;
+ scode = cd->start_code + GET(code, 1);
if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
+
+ /* Completed backwards reference */
+
do
{
- if (could_be_empty_branch(scode, endcode, utf8, cd))
+ if (could_be_empty_branch(scode, endcode, utf, cd))
{
empty_branch = TRUE;
break;
@@ -1978,13 +2385,39 @@
scode += GET(scode, 1);
}
while (*scode == OP_ALT);
+
if (!empty_branch) return FALSE; /* All branches are non-empty */
continue;
}
+ /* Groups with zero repeats can of course be empty; skip them. */
+
+ if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO ||
+ c == OP_BRAPOSZERO)
+ {
+ code += PRIV(OP_lengths)[c];
+ do code += GET(code, 1); while (*code == OP_ALT);
+ c = *code;
+ continue;
+ }
+
+ /* A nested group that is already marked as "could be empty" can just be
+ skipped. */
+
+ if (c == OP_SBRA || c == OP_SBRAPOS ||
+ c == OP_SCBRA || c == OP_SCBRAPOS)
+ {
+ do code += GET(code, 1); while (*code == OP_ALT);
+ c = *code;
+ continue;
+ }
+
/* For other groups, scan the branches. */
- if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE || c == OP_COND)
+ if (c == OP_BRA || c == OP_BRAPOS ||
+ c == OP_CBRA || c == OP_CBRAPOS ||
+ c == OP_ONCE || c == OP_ONCE_NC ||
+ c == OP_COND)
{
BOOL empty_branch;
if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */
@@ -2000,7 +2433,7 @@
empty_branch = FALSE;
do
{
- if (!empty_branch && could_be_empty_branch(code, endcode, utf8, cd))
+ if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd))
empty_branch = TRUE;
code += GET(code, 1);
}
@@ -2018,11 +2451,11 @@
{
/* Check for quantifiers after a class. XCLASS is used for classes that
cannot be represented just by a bit map. This includes negated single
- high-valued characters. The length in _pcre_OP_lengths[] is zero; the
+ high-valued characters. The length in PRIV(OP_lengths)[] is zero; the
actual length is stored in the compiled code, so we must update "code"
here. */
-#ifdef SUPPORT_UTF8
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
case OP_XCLASS:
ccode = code += GET(code, 1);
goto CHECK_CLASS_REPEAT;
@@ -2030,9 +2463,9 @@
case OP_CLASS:
case OP_NCLASS:
- ccode = code + 33;
+ ccode = code + PRIV(OP_lengths)[OP_CLASS];
-#ifdef SUPPORT_UTF8
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
CHECK_CLASS_REPEAT:
#endif
@@ -2071,8 +2504,9 @@
case OP_ALLANY:
case OP_ANYBYTE:
case OP_CHAR:
- case OP_CHARNC:
+ case OP_CHARI:
case OP_NOT:
+ case OP_NOTI:
case OP_PLUS:
case OP_MINPLUS:
case OP_POSPLUS:
@@ -2104,7 +2538,8 @@
case OP_TYPEUPTO:
case OP_TYPEMINUPTO:
case OP_TYPEPOSUPTO:
- if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
+ if (code[1 + IMM2_SIZE] == OP_PROP
+ || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
break;
/* End of branch */
@@ -2112,26 +2547,36 @@
case OP_KET:
case OP_KETRMAX:
case OP_KETRMIN:
+ case OP_KETRPOS:
case OP_ALT:
return TRUE;
/* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO,
MINUPTO, and POSUPTO may be followed by a multibyte character */
-#ifdef SUPPORT_UTF8
+#ifdef SUPPORT_UTF
case OP_STAR:
+ case OP_STARI:
case OP_MINSTAR:
+ case OP_MINSTARI:
case OP_POSSTAR:
+ case OP_POSSTARI:
case OP_QUERY:
+ case OP_QUERYI:
case OP_MINQUERY:
+ case OP_MINQUERYI:
case OP_POSQUERY:
- if (utf8 && code[1] >= 0xc0) code += _pcre_utf8_table4[code[1] & 0x3f];
+ case OP_POSQUERYI:
+ if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]);
break;
case OP_UPTO:
+ case OP_UPTOI:
case OP_MINUPTO:
+ case OP_MINUPTOI:
case OP_POSUPTO:
- if (utf8 && code[3] >= 0xc0) code += _pcre_utf8_table4[code[3] & 0x3f];
+ case OP_POSUPTOI:
+ if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]);
break;
#endif
@@ -2145,7 +2590,7 @@
break;
case OP_THEN_ARG:
- code += code[1+LINK_SIZE];
+ code += code[1];
break;
/* None of the remaining opcodes are required to match a character. */
@@ -2168,24 +2613,26 @@
the current branch of the current pattern to see if it could match the empty
string. If it could, we must look outwards for branches at other levels,
stopping when we pass beyond the bracket which is the subject of the recursion.
+This function is called only during the real compile, not during the
+pre-compile.
Arguments:
code points to start of the recursion
endcode points to where to stop (current RECURSE item)
bcptr points to the chain of current (unclosed) branch starts
- utf8 TRUE if in UTF-8 mode
+ utf TRUE if in UTF-8 / UTF-16 mode
cd pointers to tables etc
Returns: TRUE if what is matched could be empty
*/
static BOOL
-could_be_empty(const uschar *code, const uschar *endcode, branch_chain *bcptr,
- BOOL utf8, compile_data *cd)
+could_be_empty(const pcre_uchar *code, const pcre_uchar *endcode,
+ branch_chain *bcptr, BOOL utf, compile_data *cd)
{
while (bcptr != NULL && bcptr->current_branch >= code)
{
- if (!could_be_empty_branch(bcptr->current_branch, endcode, utf8, cd))
+ if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd))
return FALSE;
bcptr = bcptr->outer;
}
@@ -2218,6 +2665,17 @@
"l\ower". This is a lesser evil that not diagnosing bad classes when Perl does,
I think.
+A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
+It seems that the appearance of a nested POSIX class supersedes an apparent
+external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or
+a digit.
+
+In Perl, unescaped square brackets may also appear as part of class names. For
+example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for
+[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not
+seem right at all. PCRE does not allow closing square brackets in POSIX class
+names.
+
Arguments:
ptr pointer to the initial [
endptr where to return the end pointer
@@ -2226,20 +2684,27 @@
*/
static BOOL
-check_posix_syntax(const uschar *ptr, const uschar **endptr)
+check_posix_syntax(const pcre_uchar *ptr, const pcre_uchar **endptr)
{
int terminator; /* Don't combine these lines; the Solaris cc */
terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */
for (++ptr; *ptr != 0; ptr++)
{
- if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) ptr++; else
+ if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
+ ptr++;
+ else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
+ else
{
- if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
{
*endptr = ptr;
return TRUE;
}
+ if (*ptr == CHAR_LEFT_SQUARE_BRACKET &&
+ (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
+ ptr[1] == CHAR_EQUALS_SIGN) &&
+ check_posix_syntax(ptr, endptr))
+ return FALSE;
}
}
return FALSE;
@@ -2263,14 +2728,14 @@
*/
static int
-check_posix_name(const uschar *ptr, int len)
+check_posix_name(const pcre_uchar *ptr, int len)
{
const char *pn = posix_names;
register int yield = 0;
while (posix_name_lengths[yield] != 0)
{
if (len == posix_name_lengths[yield] &&
- strncmp((const char *)ptr, pn, len) == 0) return yield;
+ STRNCMP_UC_C8(ptr, pn, len) == 0) return yield;
pn += posix_name_lengths[yield] + 1;
yield++;
}
@@ -2302,7 +2767,7 @@
Arguments:
group points to the start of the group
adjust the amount by which the group is to be moved
- utf8 TRUE in UTF-8 mode
+ utf TRUE in UTF-8 / UTF-16 mode
cd contains pointers to tables etc.
save_hwm the hwm forward reference pointer at the start of the group
@@ -2310,15 +2775,15 @@
*/
static void
-adjust_recurse(uschar *group, int adjust, BOOL utf8, compile_data *cd,
- uschar *save_hwm)
+adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
+ pcre_uchar *save_hwm)
{
-uschar *ptr = group;
+pcre_uchar *ptr = group;
-while ((ptr = (uschar *)find_recurse(ptr, utf8)) != NULL)
+while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
{
int offset;
- uschar *hc;
+ pcre_uchar *hc;
/* See if this recursion is on the forward reference list. If so, adjust the
reference. */
@@ -2363,14 +2828,14 @@
Returns: new code pointer
*/
-static uschar *
-auto_callout(uschar *code, const uschar *ptr, compile_data *cd)
+static pcre_uchar *
+auto_callout(pcre_uchar *code, const pcre_uchar *ptr, compile_data *cd)
{
*code++ = OP_CALLOUT;
*code++ = 255;
PUT(code, 0, (int)(ptr - cd->start_pattern)); /* Pattern offset */
PUT(code, LINK_SIZE, 0); /* Default length */
-return code + 2*LINK_SIZE;
+return code + 2 * LINK_SIZE;
}
@@ -2392,7 +2857,7 @@
*/
static void
-complete_callout(uschar *previous_callout, const uschar *ptr, compile_data *cd)
+complete_callout(pcre_uchar *previous_callout, const pcre_uchar *ptr, compile_data *cd)
{
int length = (int)(ptr - cd->start_pattern - GET(previous_callout, 2));
PUT(previous_callout, 2 + LINK_SIZE, length);
@@ -2475,7 +2940,7 @@
prop->chartype == ucp_Lt) == negated;
case PT_GC:
- return (pdata == _pcre_ucp_gentype[prop->chartype]) == negated;
+ return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated;
case PT_PC:
return (pdata == prop->chartype) == negated;
@@ -2486,23 +2951,23 @@
/* These are specials */
case PT_ALNUM:
- return (_pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N) == negated;
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated;
case PT_SPACE: /* Perl space */
- return (_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
== negated;
case PT_PXSPACE: /* POSIX space */
- return (_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
c == CHAR_FF || c == CHAR_CR)
== negated;
case PT_WORD:
- return (_pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N ||
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
c == CHAR_UNDERSCORE) == negated;
}
return FALSE;
@@ -2521,7 +2986,7 @@
Arguments:
previous pointer to the repeated opcode
- utf8 TRUE in UTF-8 mode
+ utf TRUE in UTF-8 / UTF-16 mode
ptr next character in pattern
options options bits
cd contains pointers to tables etc.
@@ -2530,10 +2995,10 @@
*/
static BOOL
-check_auto_possessive(const uschar *previous, BOOL utf8, const uschar *ptr,
- int options, compile_data *cd)
+check_auto_possessive(const pcre_uchar *previous, BOOL utf,
+ const pcre_uchar *ptr, int options, compile_data *cd)
{
-int c, next;
+pcre_int32 c, next;
int op_code = *previous++;
/* Skip whitespace and comments in extended mode */
@@ -2542,7 +3007,7 @@
{
for (;;)
{
- while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
if (*ptr == CHAR_NUMBER_SIGN)
{
ptr++;
@@ -2550,8 +3015,8 @@
{
if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
ptr++;
-#ifdef SUPPORT_UTF8
- if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
#endif
}
}
@@ -2569,15 +3034,13 @@
if (temperrorcode != 0) return FALSE;
ptr++; /* Point after the escape sequence */
}
-
-else if ((cd->ctypes[*ptr] & ctype_meta) == 0)
+else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0)
{
-#ifdef SUPPORT_UTF8
- if (utf8) { GETCHARINC(next, ptr); } else
+#ifdef SUPPORT_UTF
+ if (utf) { GETCHARINC(next, ptr); } else
#endif
next = *ptr++;
}
-
else return FALSE;
/* Skip whitespace and comments in extended mode */
@@ -2586,7 +3049,7 @@
{
for (;;)
{
- while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
if (*ptr == CHAR_NUMBER_SIGN)
{
ptr++;
@@ -2594,8 +3057,8 @@
{
if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
ptr++;
-#ifdef SUPPORT_UTF8
- if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
#endif
}
}
@@ -2606,7 +3069,7 @@
/* If the next thing is itself optional, we have to give up. */
if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
- strncmp((char *)ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
+ STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
return FALSE;
/* Now compare the next item with the previous opcode. First, handle cases when
@@ -2615,26 +3078,26 @@
if (next >= 0) switch(op_code)
{
case OP_CHAR:
-#ifdef SUPPORT_UTF8
+#ifdef SUPPORT_UTF
GETCHARTEST(c, previous);
#else
c = *previous;
#endif
return c != next;
- /* For CHARNC (caseless character) we must check the other case. If we have
+ /* For CHARI (caseless character) we must check the other case. If we have
Unicode property support, we can use it to test the other case of
high-valued characters. */
- case OP_CHARNC:
-#ifdef SUPPORT_UTF8
+ case OP_CHARI:
+#ifdef SUPPORT_UTF
GETCHARTEST(c, previous);
#else
c = *previous;
#endif
if (c == next) return FALSE;
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
unsigned int othercase;
if (next < 128) othercase = cd->fcc[next]; else
@@ -2646,50 +3109,60 @@
return (unsigned int)c != othercase;
}
else
-#endif /* SUPPORT_UTF8 */
- return (c != cd->fcc[next]); /* Non-UTF-8 mode */
-
- /* For OP_NOT, its data is always a single-byte character. */
+#endif /* SUPPORT_UTF */
+ return (c != TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */
case OP_NOT:
- if ((c = *previous) == next) return TRUE;
- if ((options & PCRE_CASELESS) == 0) return FALSE;
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifdef SUPPORT_UTF
+ GETCHARTEST(c, previous);
+#else
+ c = *previous;
+#endif
+ return c == next;
+
+ case OP_NOTI:
+#ifdef SUPPORT_UTF
+ GETCHARTEST(c, previous);
+#else
+ c = *previous;
+#endif
+ if (c == next) return TRUE;
+#ifdef SUPPORT_UTF
+ if (utf)
{
unsigned int othercase;
if (next < 128) othercase = cd->fcc[next]; else
#ifdef SUPPORT_UCP
- othercase = UCD_OTHERCASE(next);
+ othercase = UCD_OTHERCASE((unsigned int)next);
#else
othercase = NOTACHAR;
#endif
return (unsigned int)c == othercase;
}
else
-#endif /* SUPPORT_UTF8 */
- return (c == cd->fcc[next]); /* Non-UTF-8 mode */
+#endif /* SUPPORT_UTF */
+ return (c == TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */
/* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set.
When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */
case OP_DIGIT:
- return next > 127 || (cd->ctypes[next] & ctype_digit) == 0;
+ return next > 255 || (cd->ctypes[next] & ctype_digit) == 0;
case OP_NOT_DIGIT:
- return next <= 127 && (cd->ctypes[next] & ctype_digit) != 0;
+ return next <= 255 && (cd->ctypes[next] & ctype_digit) != 0;
case OP_WHITESPACE:
- return next > 127 || (cd->ctypes[next] & ctype_space) == 0;
+ return next > 255 || (cd->ctypes[next] & ctype_space) == 0;
case OP_NOT_WHITESPACE:
- return next <= 127 && (cd->ctypes[next] & ctype_space) != 0;
+ return next <= 255 && (cd->ctypes[next] & ctype_space) != 0;
case OP_WORDCHAR:
- return next > 127 || (cd->ctypes[next] & ctype_word) == 0;
+ return next > 255 || (cd->ctypes[next] & ctype_word) == 0;
case OP_NOT_WORDCHAR:
- return next <= 127 && (cd->ctypes[next] & ctype_word) != 0;
+ return next <= 255 && (cd->ctypes[next] & ctype_word) != 0;
case OP_HSPACE:
case OP_NOT_HSPACE:
@@ -2758,8 +3231,8 @@
switch(op_code)
{
case OP_CHAR:
- case OP_CHARNC:
-#ifdef SUPPORT_UTF8
+ case OP_CHARI:
+#ifdef SUPPORT_UTF
GETCHARTEST(c, previous);
#else
c = *previous;
@@ -2767,22 +3240,22 @@
switch(-next)
{
case ESC_d:
- return c > 127 || (cd->ctypes[c] & ctype_digit) == 0;
+ return c > 255 || (cd->ctypes[c] & ctype_digit) == 0;
case ESC_D:
- return c <= 127 && (cd->ctypes[c] & ctype_digit) != 0;
+ return c <= 255 && (cd->ctypes[c] & ctype_digit) != 0;
case ESC_s:
- return c > 127 || (cd->ctypes[c] & ctype_space) == 0;
+ return c > 255 || (cd->ctypes[c] & ctype_space) == 0;
case ESC_S:
- return c <= 127 && (cd->ctypes[c] & ctype_space) != 0;
+ return c <= 255 && (cd->ctypes[c] & ctype_space) != 0;
case ESC_w:
- return c > 127 || (cd->ctypes[c] & ctype_word) == 0;
+ return c > 255 || (cd->ctypes[c] & ctype_word) == 0;
case ESC_W:
- return c <= 127 && (cd->ctypes[c] & ctype_word) != 0;
+ return c <= 255 && (cd->ctypes[c] & ctype_word) != 0;
case ESC_h:
case ESC_H:
@@ -2864,7 +3337,7 @@
to the original \d etc. At this point, ptr will point to a zero byte. */
if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
- strncmp((char *)ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
+ STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
return FALSE;
/* Do the property check. */
@@ -2891,10 +3364,10 @@
return next == -ESC_d;
case OP_WHITESPACE:
- return next == -ESC_S || next == -ESC_d || next == -ESC_w || next == -ESC_R;
+ return next == -ESC_S || next == -ESC_d || next == -ESC_w;
case OP_NOT_WHITESPACE:
- return next == -ESC_s || next == -ESC_h || next == -ESC_v;
+ return next == -ESC_s || next == -ESC_h || next == -ESC_v || next == -ESC_R;
case OP_HSPACE:
return next == -ESC_S || next == -ESC_H || next == -ESC_d ||
@@ -2942,9 +3415,10 @@
codeptr points to the pointer to the current code point
ptrptr points to the current pattern pointer
errorcodeptr points to error code variable
- firstbyteptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE)
- reqbyteptr set to the last literal character required, else < 0
+ firstcharptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE)
+ reqcharptr set to the last literal character required, else < 0
bcptr points to current branch chain
+ cond_depth conditional nesting depth
cd contains pointers to tables etc.
lengthptr NULL during the real compile phase
points to length accumulator during pre-compile phase
@@ -2954,44 +3428,54 @@
*/
static BOOL
-compile_branch(int *optionsptr, uschar **codeptr, const uschar **ptrptr,
- int *errorcodeptr, int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr,
+compile_branch(int *optionsptr, pcre_uchar **codeptr,
+ const pcre_uchar **ptrptr, int *errorcodeptr, pcre_int32 *firstcharptr,
+ pcre_int32 *reqcharptr, branch_chain *bcptr, int cond_depth,
compile_data *cd, int *lengthptr)
{
int repeat_type, op_type;
int repeat_min = 0, repeat_max = 0; /* To please picky compilers */
int bravalue = 0;
int greedy_default, greedy_non_default;
-int firstbyte, reqbyte;
-int zeroreqbyte, zerofirstbyte;
-int req_caseopt, reqvary, tempreqvary;
-int options = *optionsptr;
+pcre_int32 firstchar, reqchar;
+pcre_int32 zeroreqchar, zerofirstchar;
+pcre_int32 req_caseopt, reqvary, tempreqvary;
+int options = *optionsptr; /* May change dynamically */
int after_manual_callout = 0;
int length_prevgroup = 0;
register int c;
-register uschar *code = *codeptr;
-uschar *last_code = code;
-uschar *orig_code = code;
-uschar *tempcode;
+register pcre_uchar *code = *codeptr;
+pcre_uchar *last_code = code;
+pcre_uchar *orig_code = code;
+pcre_uchar *tempcode;
BOOL inescq = FALSE;
-BOOL groupsetfirstbyte = FALSE;
-const uschar *ptr = *ptrptr;
-const uschar *tempptr;
-const uschar *nestptr = NULL;
-uschar *previous = NULL;
-uschar *previous_callout = NULL;
-uschar *save_hwm = NULL;
-uschar classbits[32];
-
-#ifdef SUPPORT_UTF8
-BOOL class_utf8;
-BOOL utf8 = (options & PCRE_UTF8) != 0;
-uschar *class_utf8data;
-uschar *class_utf8data_base;
-uschar utf8_char[6];
+BOOL groupsetfirstchar = FALSE;
+const pcre_uchar *ptr = *ptrptr;
+const pcre_uchar *tempptr;
+const pcre_uchar *nestptr = NULL;
+pcre_uchar *previous = NULL;
+pcre_uchar *previous_callout = NULL;
+pcre_uchar *save_hwm = NULL;
+pcre_uint8 classbits[32];
+
+/* We can fish out the UTF-8 setting once and for all into a BOOL, but we
+must not do this for other options (e.g. PCRE_EXTENDED) because they may change
+dynamically as we process the pattern. */
+
+#ifdef SUPPORT_UTF
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+BOOL utf = (options & PCRE_UTF8) != 0;
+pcre_uchar utf_chars[6];
#else
-BOOL utf8 = FALSE;
-uschar *utf8_char = NULL;
+BOOL utf = FALSE;
+#endif
+
+/* Helper variables for OP_XCLASS opcode (for characters > 255). */
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+BOOL xclass;
+pcre_uchar *class_uchardata;
+pcre_uchar *class_uchardata_base;
#endif
#ifdef PCRE_DEBUG
@@ -3005,22 +3489,23 @@
/* Initialize no first byte, no required byte. REQ_UNSET means "no char
matching encountered yet". It gets changed to REQ_NONE if we hit something that
-matches a non-fixed char first char; reqbyte just remains unset if we never
+matches a non-fixed char first char; reqchar just remains unset if we never
find one.
When we hit a repeat whose minimum is zero, we may have to adjust these values
to take the zero repeat into account. This is implemented by setting them to
-zerofirstbyte and zeroreqbyte when such a repeat is encountered. The individual
+zerofirstbyte and zeroreqchar when such a repeat is encountered. The individual
item types that can be repeated set these backoff variables appropriately. */
-firstbyte = reqbyte = zerofirstbyte = zeroreqbyte = REQ_UNSET;
+firstchar = reqchar = zerofirstchar = zeroreqchar = REQ_UNSET;
-/* The variable req_caseopt contains either the REQ_CASELESS value or zero,
-according to the current setting of the caseless flag. REQ_CASELESS is a bit
-value > 255. It is added into the firstbyte or reqbyte variables to record the
-case status of the value. This is used only for ASCII characters. */
+/* The variable req_caseopt contains either the REQ_CASELESS value
+or zero, according to the current setting of the caseless flag. The
+REQ_CASELESS leaves the lower 28 bit empty. It is added into the
+firstchar or reqchar variables to record the case status of the
+value. This is used only for ASCII characters. */
-req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0;
+req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS:0;
/* Switch on next character until the end of the branch */
@@ -3032,19 +3517,20 @@
BOOL is_quantifier;
BOOL is_recurse;
BOOL reset_bracount;
- int class_charcount;
- int class_lastchar;
+ int class_has_8bitchar;
+ int class_single_char;
int newoptions;
int recno;
int refsign;
int skipbytes;
- int subreqbyte;
- int subfirstbyte;
+ int subreqchar;
+ int subfirstchar;
int terminator;
int mclength;
- uschar mcbuffer[8];
+ int tempbracount;
+ pcre_uchar mcbuffer[8];
- /* Get next byte in the pattern */
+ /* Get next character in the pattern */
c = *ptr;
@@ -3066,7 +3552,8 @@
#ifdef PCRE_DEBUG
if (code > cd->hwm) cd->hwm = code; /* High water info */
#endif
- if (code > cd->start_workspace + WORK_SIZE_CHECK) /* Check for overrun */
+ if (code > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */
{
*errorcodeptr = ERR52;
goto FAILED;
@@ -3089,7 +3576,8 @@
}
*lengthptr += (int)(code - last_code);
- DPRINTF(("length=%d added %d c=%c\n", *lengthptr, code - last_code, c));
+ DPRINTF(("length=%d added %d c=%c (0x%x)\n", *lengthptr,
+ (int)(code - last_code), c, c));
/* If "previous" is set and it is not at the start of the work space, move
it back to there, in order to avoid filling up the work space. Otherwise,
@@ -3099,7 +3587,7 @@
{
if (previous > orig_code)
{
- memmove(orig_code, previous, code - previous);
+ memmove(orig_code, previous, IN_UCHARS(code - previous));
code -= previous - orig_code;
previous = orig_code;
}
@@ -3115,7 +3603,8 @@
/* In the real compile phase, just check the workspace used by the forward
reference list. */
- else if (cd->hwm > cd->start_workspace + WORK_SIZE_CHECK)
+ else if (cd->hwm > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN)
{
*errorcodeptr = ERR52;
goto FAILED;
@@ -3163,11 +3652,11 @@
previous_callout = NULL;
}
- /* In extended mode, skip white space and comments */
+ /* In extended mode, skip white space and comments. */
if ((options & PCRE_EXTENDED) != 0)
{
- if ((cd->ctypes[c] & ctype_space) != 0) continue;
+ if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue;
if (c == CHAR_NUMBER_SIGN)
{
ptr++;
@@ -3175,8 +3664,8 @@
{
if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
ptr++;
-#ifdef SUPPORT_UTF8
- if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
#endif
}
if (*ptr != 0) continue;
@@ -3200,8 +3689,8 @@
case 0: /* The branch terminates at string end */
case CHAR_VERTICAL_LINE: /* or | or ) */
case CHAR_RIGHT_PARENTHESIS:
- *firstbyteptr = firstbyte;
- *reqbyteptr = reqbyte;
+ *firstcharptr = firstchar;
+ *reqcharptr = reqchar;
*codeptr = code;
*ptrptr = ptr;
if (lengthptr != NULL)
@@ -3222,26 +3711,27 @@
the setting of any following char as a first character. */
case CHAR_CIRCUMFLEX_ACCENT:
+ previous = NULL;
if ((options & PCRE_MULTILINE) != 0)
{
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ *code++ = OP_CIRCM;
}
- previous = NULL;
- *code++ = OP_CIRC;
+ else *code++ = OP_CIRC;
break;
case CHAR_DOLLAR_SIGN:
previous = NULL;
- *code++ = OP_DOLL;
+ *code++ = ((options & PCRE_MULTILINE) != 0)? OP_DOLLM : OP_DOLL;
break;
/* There can never be a first char if '.' is first, whatever happens about
- repeats. The value of reqbyte doesn't change either. */
+ repeats. The value of reqchar doesn't change either. */
case CHAR_DOT:
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
- zerofirstbyte = firstbyte;
- zeroreqbyte = reqbyte;
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
previous = code;
*code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY;
break;
@@ -3296,8 +3786,7 @@
{
if (ptr[1] == CHAR_E)
ptr++;
- else if (strncmp((const char *)ptr+1,
- STR_Q STR_BACKSLASH STR_E, 3) == 0)
+ else if (STRNCMP_UC_C8(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0)
ptr += 3;
else
break;
@@ -3316,8 +3805,8 @@
(cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
{
*code++ = negate_class? OP_ALLANY : OP_FAIL;
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
- zerofirstbyte = firstbyte;
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
break;
}
@@ -3327,24 +3816,25 @@
should_flip_negation = FALSE;
- /* Keep a count of chars with values < 256 so that we can optimize the case
- of just a single character (as long as it's < 256). However, For higher
- valued UTF-8 characters, we don't yet do any optimization. */
+ /* For optimization purposes, we track some properties of the class.
+ class_has_8bitchar will be non-zero, if the class contains at least one
+ < 256 character. class_single_char will be 1 if the class contains only
+ a single character. */
- class_charcount = 0;
- class_lastchar = -1;
+ class_has_8bitchar = 0;
+ class_single_char = 0;
/* Initialize the 32-char bit map to all zeros. We build the map in a
temporary bit of memory, in case the class contains only 1 character (less
than 256), because in that case the compiled code doesn't use the bit map.
*/
- memset(classbits, 0, 32 * sizeof(uschar));
+ memset(classbits, 0, 32 * sizeof(pcre_uint8));
-#ifdef SUPPORT_UTF8
- class_utf8 = FALSE; /* No chars >= 256 */
- class_utf8data = code + LINK_SIZE + 2; /* For UTF-8 items */
- class_utf8data_base = class_utf8data; /* For resetting in pass 1 */
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ xclass = FALSE; /* No chars >= 256 */
+ class_uchardata = code + LINK_SIZE + 2; /* For UTF-8 items */
+ class_uchardata_base = class_uchardata; /* For resetting in pass 1 */
#endif
/* Process characters until ] is reached. By writing this as a "do" it
@@ -3353,25 +3843,26 @@
if (c != 0) do
{
- const uschar *oldptr;
+ const pcre_uchar *oldptr;
-#ifdef SUPPORT_UTF8
- if (utf8 && c > 127)
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(c))
{ /* Braces are required because the */
GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */
}
+#endif
- /* In the pre-compile phase, accumulate the length of any UTF-8 extra
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ /* In the pre-compile phase, accumulate the length of any extra
data and reset the pointer. This is so that very large classes that
- contain a zillion UTF-8 characters no longer overwrite the work space
+ contain a zillion > 255 characters no longer overwrite the work space
(which is on the stack). */
if (lengthptr != NULL)
{
- *lengthptr += class_utf8data - class_utf8data_base;
- class_utf8data = class_utf8data_base;
+ *lengthptr += class_uchardata - class_uchardata_base;
+ class_uchardata = class_uchardata_base;
}
-
#endif
/* Inside \Q...\E everything is literal except \E */
@@ -3399,8 +3890,8 @@
{
BOOL local_negate = FALSE;
int posix_class, taboffset, tabopt;
- register const uschar *cbits = cd->cbits;
- uschar pbits[32];
+ register const pcre_uint8 *cbits = cd->cbits;
+ pcre_uint8 pbits[32];
if (ptr[1] != CHAR_COLON)
{
@@ -3455,7 +3946,7 @@
/* Copy in the first table (always present) */
memcpy(pbits, cbits + posix_class_maps[posix_class],
- 32 * sizeof(uschar));
+ 32 * sizeof(pcre_uint8));
/* If there is a second table, add or remove it as required. */
@@ -3486,16 +3977,20 @@
for (c = 0; c < 32; c++) classbits[c] |= pbits[c];
ptr = tempptr + 1;
- class_charcount = 10; /* Set > 1; assumes more than 1 per class */
+ /* Every class contains at least one < 256 characters. */
+ class_has_8bitchar = 1;
+ /* Every class contains at least two characters. */
+ class_single_char = 2;
continue; /* End of POSIX syntax handling */
}
/* Backslash may introduce a single character, or it may introduce one
of the specials, which just set a flag. The sequence \b is a special
case. Inside a class (and only there) it is treated as backspace. We
- assume that other escapes have more than one character in them, so set
- class_charcount bigger than one. Unrecognized escapes fall through and
- are either treated as literal characters (by default), or are faulted if
+ assume that other escapes have more than one character in them, so
+ speculatively set both class_has_8bitchar and class_single_char bigger
+ than one. Unrecognized escapes fall through and are either treated
+ as literal characters (by default), or are faulted if
PCRE_EXTRA is set. */
if (c == CHAR_BACKSLASH)
@@ -3504,6 +3999,11 @@
if (*errorcodeptr != 0) goto FAILED;
if (-c == ESC_b) c = CHAR_BS; /* \b is backspace in a class */
+ else if (-c == ESC_N) /* \N is not supported in a class */
+ {
+ *errorcodeptr = ERR71;
+ goto FAILED;
+ }
else if (-c == ESC_Q) /* Handle start of quoted string */
{
if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
@@ -3517,8 +4017,11 @@
if (c < 0)
{
- register const uschar *cbits = cd->cbits;
- class_charcount += 2; /* Greater than 1 is what matters */
+ register const pcre_uint8 *cbits = cd->cbits;
+ /* Every class contains at least two < 256 characters. */
+ class_has_8bitchar++;
+ /* Every class contains at least two characters. */
+ class_single_char += 2;
switch (-c)
{
@@ -3531,7 +4034,7 @@
case ESC_SU:
nestptr = ptr;
ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */
- class_charcount -= 2; /* Undo! */
+ class_has_8bitchar--; /* Undo! */
continue;
#endif
case ESC_d:
@@ -3572,23 +4075,38 @@
SETBIT(classbits, 0x09); /* VT */
SETBIT(classbits, 0x20); /* SPACE */
SETBIT(classbits, 0xa0); /* NSBP */
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x1680;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x180e;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2000;
+ *class_uchardata++ = 0x200a;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x202f;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x205f;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x3000;
+#elif defined SUPPORT_UTF
+ if (utf)
{
- class_utf8 = TRUE;
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data);
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data);
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data);
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data);
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data);
+ xclass = TRUE;
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x1680, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x180e, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2000, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x200a, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x202f, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x205f, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x3000, class_uchardata);
}
#endif
continue;
@@ -3606,32 +4124,59 @@
}
classbits[c] |= x;
}
-
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x0100;
+ *class_uchardata++ = 0x167f;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x1681;
+ *class_uchardata++ = 0x180d;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x180f;
+ *class_uchardata++ = 0x1fff;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x200b;
+ *class_uchardata++ = 0x202e;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2030;
+ *class_uchardata++ = 0x205e;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2060;
+ *class_uchardata++ = 0x2fff;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x3001;
+#ifdef SUPPORT_UTF
+ if (utf)
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
+ else
+#endif
+ *class_uchardata++ = 0xffff;
+#elif defined SUPPORT_UTF
+ if (utf)
{
- class_utf8 = TRUE;
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x167f, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x1681, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x180d, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x180f, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x1fff, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x200b, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x202e, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2030, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x205e, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2060, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x2fff, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x3001, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
}
#endif
continue;
@@ -3642,13 +4187,18 @@
SETBIT(classbits, 0x0c); /* FF */
SETBIT(classbits, 0x0d); /* CR */
SETBIT(classbits, 0x85); /* NEL */
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2028;
+ *class_uchardata++ = 0x2029;
+#elif defined SUPPORT_UTF
+ if (utf)
{
- class_utf8 = TRUE;
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2028, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x2029, class_uchardata);
}
#endif
continue;
@@ -3670,16 +4220,29 @@
classbits[c] |= x;
}
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x0100;
+ *class_uchardata++ = 0x2027;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x202a;
+#ifdef SUPPORT_UTF
+ if (utf)
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
+ else
+#endif
+ *class_uchardata++ = 0xffff;
+#elif defined SUPPORT_UTF
+ if (utf)
{
- class_utf8 = TRUE;
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data);
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
- class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x2027, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x202a, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
}
#endif
continue;
@@ -3692,12 +4255,12 @@
int pdata;
int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr);
if (ptype < 0) goto FAILED;
- class_utf8 = TRUE;
- *class_utf8data++ = ((-c == ESC_p) != negated)?
+ xclass = TRUE;
+ *class_uchardata++ = ((-c == ESC_p) != negated)?
XCL_PROP : XCL_NOTPROP;
- *class_utf8data++ = ptype;
- *class_utf8data++ = pdata;
- class_charcount -= 2; /* Not a < 256 character */
+ *class_uchardata++ = ptype;
+ *class_uchardata++ = pdata;
+ class_has_8bitchar--; /* Undo! */
continue;
}
#endif
@@ -3711,14 +4274,15 @@
*errorcodeptr = ERR7;
goto FAILED;
}
- class_charcount -= 2; /* Undo the default count from above */
- c = *ptr; /* Get the final character and fall through */
+ class_has_8bitchar--; /* Undo the speculative increase. */
+ class_single_char -= 2; /* Undo the speculative increase. */
+ c = *ptr; /* Get the final character and fall through */
break;
}
}
/* Fall through if we have a single character (c >= 0). This may be
- greater than 256 in UTF-8 mode. */
+ greater than 256. */
} /* End of backslash handling */
@@ -3766,8 +4330,8 @@
goto LONE_SINGLE_CHARACTER;
}
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{ /* Braces are required because the */
GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */
}
@@ -3811,22 +4375,36 @@
if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
+ /* Since we found a character range, single character optimizations
+ cannot be done anymore. */
+ class_single_char = 2;
+
/* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless
matching, we have to use an XCLASS with extra data items. Caseless
matching for characters > 127 is available only if UCP support is
available. */
-#ifdef SUPPORT_UTF8
- if (utf8 && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127)))
+#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8)
+ if ((d > 255) || (utf && ((options & PCRE_CASELESS) != 0 && d > 127)))
+#elif defined SUPPORT_UTF
+ if (utf && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127)))
+#elif !(defined COMPILE_PCRE8)
+ if (d > 255)
+#endif
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
{
- class_utf8 = TRUE;
+ xclass = TRUE;
/* With UCP support, we can find the other case equivalents of
the relevant characters. There may be several ranges. Optimize how
they fit with the basic range. */
#ifdef SUPPORT_UCP
+#ifndef COMPILE_PCRE8
+ if (utf && (options & PCRE_CASELESS) != 0)
+#else
if ((options & PCRE_CASELESS) != 0)
+#endif
{
unsigned int occ, ocd;
unsigned int cc = c;
@@ -3852,14 +4430,14 @@
if (occ == ocd)
{
- *class_utf8data++ = XCL_SINGLE;
+ *class_uchardata++ = XCL_SINGLE;
}
else
{
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(occ, class_utf8data);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(occ, class_uchardata);
}
- class_utf8data += _pcre_ord2utf8(ocd, class_utf8data);
+ class_uchardata += PRIV(ord2utf)(ocd, class_uchardata);
}
}
#endif /* SUPPORT_UCP */
@@ -3867,33 +4445,69 @@
/* Now record the original range, possibly modified for UCP caseless
overlapping ranges. */
- *class_utf8data++ = XCL_RANGE;
- class_utf8data += _pcre_ord2utf8(c, class_utf8data);
- class_utf8data += _pcre_ord2utf8(d, class_utf8data);
+ *class_uchardata++ = XCL_RANGE;
+#ifdef SUPPORT_UTF
+#ifndef COMPILE_PCRE8
+ if (utf)
+ {
+ class_uchardata += PRIV(ord2utf)(c, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(d, class_uchardata);
+ }
+ else
+ {
+ *class_uchardata++ = c;
+ *class_uchardata++ = d;
+ }
+#else
+ class_uchardata += PRIV(ord2utf)(c, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(d, class_uchardata);
+#endif
+#else /* SUPPORT_UTF */
+ *class_uchardata++ = c;
+ *class_uchardata++ = d;
+#endif /* SUPPORT_UTF */
/* With UCP support, we are done. Without UCP support, there is no
- caseless matching for UTF-8 characters > 127; we can use the bit map
- for the smaller ones. */
+ caseless matching for UTF characters > 127; we can use the bit map
+ for the smaller ones. As for 16 bit characters without UTF, we
+ can still use */
#ifdef SUPPORT_UCP
- continue; /* With next character in the class */
-#else
- if ((options & PCRE_CASELESS) == 0 || c > 127) continue;
+#ifndef COMPILE_PCRE8
+ if (utf)
+#endif
+ continue; /* With next character in the class */
+#endif /* SUPPORT_UCP */
+#if defined SUPPORT_UTF && !defined(SUPPORT_UCP) && !(defined COMPILE_PCRE8)
+ if (utf)
+ {
+ if ((options & PCRE_CASELESS) == 0 || c > 127) continue;
+ /* Adjust upper limit and fall through to set up the map */
+ d = 127;
+ }
+ else
+ {
+ if (c > 255) continue;
+ /* Adjust upper limit and fall through to set up the map */
+ d = 255;
+ }
+#elif defined SUPPORT_UTF && !defined(SUPPORT_UCP)
+ if ((options & PCRE_CASELESS) == 0 || c > 127) continue;
/* Adjust upper limit and fall through to set up the map */
-
d = 127;
-
-#endif /* SUPPORT_UCP */
+#else
+ if (c > 255) continue;
+ /* Adjust upper limit and fall through to set up the map */
+ d = 255;
+#endif /* SUPPORT_UTF && !SUPPORT_UCP && !COMPILE_PCRE8 */
}
-#endif /* SUPPORT_UTF8 */
+#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
- /* We use the bit map for all cases when not in UTF-8 mode; else
- ranges that lie entirely within 0-127 when there is UCP support; else
- for partial ranges without UCP support. */
+ /* We use the bit map for 8 bit mode, or when the characters fall
+ partially or entirely to [0-255] ([0-127] for UCP) ranges. */
- class_charcount += d - c + 1;
- class_lastchar = d;
+ class_has_8bitchar = 1;
/* We can save a bit of time by skipping this in the pre-compile. */
@@ -3902,7 +4516,7 @@
classbits[c/8] |= (1 << (c&7));
if ((options & PCRE_CASELESS) != 0)
{
- int uc = cd->fcc[c]; /* flip case */
+ int uc = cd->fcc[c]; /* flip case */
classbits[uc/8] |= (1 << (uc&7));
}
}
@@ -3916,41 +4530,110 @@
LONE_SINGLE_CHARACTER:
- /* Handle a character that cannot go in the bit map */
+ /* Only the value of 1 matters for class_single_char. */
+
+ if (class_single_char < 2) class_single_char++;
+
+ /* If class_charcount is 1, we saw precisely one character. As long as
+ there was no use of \p or \P, in other words, no use of any XCLASS
+ features, we can optimize.
+
+ The optimization throws away the bit map. We turn the item into a
+ 1-character OP_CHAR[I] if it's positive, or OP_NOT[I] if it's negative.
+ In the positive case, it can cause firstchar to be set. Otherwise, there
+ can be no first char if this item is first, whatever repeat count may
+ follow. In the case of reqchar, save the previous value for reinstating. */
-#ifdef SUPPORT_UTF8
- if (utf8 && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127)))
+ if (class_single_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
{
- class_utf8 = TRUE;
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(c, class_utf8data);
+ ptr++;
+ zeroreqchar = reqchar;
+
+ if (negate_class)
+ {
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
+ *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT;
+#ifdef SUPPORT_UTF
+ if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
+ code += PRIV(ord2utf)(c, code);
+ else
+#endif
+ *code++ = c;
+ goto NOT_CHAR;
+ }
+
+ /* For a single, positive character, get the value into mcbuffer, and
+ then we can handle this with the normal one-character code. */
+
+#ifdef SUPPORT_UTF
+ if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
+ mclength = PRIV(ord2utf)(c, mcbuffer);
+ else
+#endif
+ {
+ mcbuffer[0] = c;
+ mclength = 1;
+ }
+ goto ONE_CHAR;
+ } /* End of 1-char optimization */
+
+ /* Handle a character that cannot go in the bit map. */
+
+#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8)
+ if ((c > 255) || (utf && ((options & PCRE_CASELESS) != 0 && c > 127)))
+#elif defined SUPPORT_UTF
+ if (utf && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127)))
+#elif !(defined COMPILE_PCRE8)
+ if (c > 255)
+#endif
+
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ {
+ xclass = TRUE;
+ *class_uchardata++ = XCL_SINGLE;
+#ifdef SUPPORT_UTF
+#ifndef COMPILE_PCRE8
+ /* In non 8 bit mode, we can get here even if we are not in UTF mode. */
+ if (!utf)
+ *class_uchardata++ = c;
+ else
+#endif
+ class_uchardata += PRIV(ord2utf)(c, class_uchardata);
+#else /* SUPPORT_UTF */
+ *class_uchardata++ = c;
+#endif /* SUPPORT_UTF */
#ifdef SUPPORT_UCP
+#ifdef COMPILE_PCRE8
if ((options & PCRE_CASELESS) != 0)
+#else
+ /* In non 8 bit mode, we can get here even if we are not in UTF mode. */
+ if (utf && (options & PCRE_CASELESS) != 0)
+#endif
{
unsigned int othercase;
- if ((othercase = UCD_OTHERCASE(c)) != c)
+ if ((int)(othercase = UCD_OTHERCASE(c)) != c)
{
- *class_utf8data++ = XCL_SINGLE;
- class_utf8data += _pcre_ord2utf8(othercase, class_utf8data);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(othercase, class_uchardata);
}
}
#endif /* SUPPORT_UCP */
}
else
-#endif /* SUPPORT_UTF8 */
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
/* Handle a single-byte character */
{
+ class_has_8bitchar = 1;
classbits[c/8] |= (1 << (c&7));
if ((options & PCRE_CASELESS) != 0)
{
- c = cd->fcc[c]; /* flip case */
+ c = cd->fcc[c]; /* flip case */
classbits[c/8] |= (1 << (c&7));
}
- class_charcount++;
- class_lastchar = c;
}
}
@@ -3971,66 +4654,13 @@
goto FAILED;
}
- /* If class_charcount is 1, we saw precisely one character whose value is
- less than 256. As long as there were no characters >= 128 and there was no
- use of \p or \P, in other words, no use of any XCLASS features, we can
- optimize.
-
- In UTF-8 mode, we can optimize the negative case only if there were no
- characters >= 128 because OP_NOT and the related opcodes like OP_NOTSTAR
- operate on single-bytes only. This is an historical hangover. Maybe one day
- we can tidy these opcodes to handle multi-byte characters.
-
- The optimization throws away the bit map. We turn the item into a
- 1-character OP_CHAR[NC] if it's positive, or OP_NOT if it's negative. Note
- that OP_NOT does not support multibyte characters. In the positive case, it
- can cause firstbyte to be set. Otherwise, there can be no first char if
- this item is first, whatever repeat count may follow. In the case of
- reqbyte, save the previous value for reinstating. */
-
-#ifdef SUPPORT_UTF8
- if (class_charcount == 1 && !class_utf8 &&
- (!utf8 || !negate_class || class_lastchar < 128))
-#else
- if (class_charcount == 1)
-#endif
- {
- zeroreqbyte = reqbyte;
-
- /* The OP_NOT opcode works on one-byte characters only. */
-
- if (negate_class)
- {
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
- zerofirstbyte = firstbyte;
- *code++ = OP_NOT;
- *code++ = class_lastchar;
- break;
- }
-
- /* For a single, positive character, get the value into mcbuffer, and
- then we can handle this with the normal one-character code. */
-
-#ifdef SUPPORT_UTF8
- if (utf8 && class_lastchar > 127)
- mclength = _pcre_ord2utf8(class_lastchar, mcbuffer);
- else
-#endif
- {
- mcbuffer[0] = class_lastchar;
- mclength = 1;
- }
- goto ONE_CHAR;
- } /* End of 1-char optimization */
-
- /* The general case - not the one-char optimization. If this is the first
- thing in the branch, there can be no first char setting, whatever the
- repeat count. Any reqbyte setting must remain unchanged after any kind of
- repeat. */
-
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
- zerofirstbyte = firstbyte;
- zeroreqbyte = reqbyte;
+ /* If this is the first thing in the branch, there can be no first char
+ setting, whatever the repeat count. Any reqchar setting must remain
+ unchanged after any kind of repeat. */
+
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
/* If there are characters with values > 255, we have to compile an
extended class, with its own opcode, unless there was a negated special
@@ -4040,29 +4670,34 @@
be listed) there are no characters < 256, we can omit the bitmap in the
actual compiled code. */
-#ifdef SUPPORT_UTF8
- if (class_utf8 && (!should_flip_negation || (options & PCRE_UCP) != 0))
+#ifdef SUPPORT_UTF
+ if (xclass && (!should_flip_negation || (options & PCRE_UCP) != 0))
+#elif !defined COMPILE_PCRE8
+ if (xclass && !should_flip_negation)
+#endif
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
{
- *class_utf8data++ = XCL_END; /* Marks the end of extra data */
+ *class_uchardata++ = XCL_END; /* Marks the end of extra data */
*code++ = OP_XCLASS;
code += LINK_SIZE;
- *code = negate_class? XCL_NOT : 0;
+ *code = negate_class? XCL_NOT:0;
/* If the map is required, move up the extra data to make room for it;
otherwise just move the code pointer to the end of the extra data. */
- if (class_charcount > 0)
+ if (class_has_8bitchar > 0)
{
*code++ |= XCL_MAP;
- memmove(code + 32, code, class_utf8data - code);
+ memmove(code + (32 / sizeof(pcre_uchar)), code,
+ IN_UCHARS(class_uchardata - code));
memcpy(code, classbits, 32);
- code = class_utf8data + 32;
+ code = class_uchardata + (32 / sizeof(pcre_uchar));
}
- else code = class_utf8data;
+ else code = class_uchardata;
/* Now fill in the complete length of the item */
- PUT(previous, 1, code - previous);
+ PUT(previous, 1, (int)(code - previous));
break; /* End of class handling */
}
#endif
@@ -4074,16 +4709,14 @@
negating it if necessary. */
*code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;
- if (negate_class)
- {
- if (lengthptr == NULL) /* Save time in the pre-compile phase */
- for (c = 0; c < 32; c++) code[c] = ~classbits[c];
- }
- else
+ if (lengthptr == NULL) /* Save time in the pre-compile phase */
{
+ if (negate_class)
+ for (c = 0; c < 32; c++) classbits[c] = ~classbits[c];
memcpy(code, classbits, 32);
}
- code += 32;
+ code += 32 / sizeof(pcre_uchar);
+ NOT_CHAR:
break;
@@ -4120,8 +4753,8 @@
if (repeat_min == 0)
{
- firstbyte = zerofirstbyte; /* Adjust for zero repeat */
- reqbyte = zeroreqbyte; /* Ditto */
+ firstchar = zerofirstchar; /* Adjust for zero repeat */
+ reqchar = zeroreqchar; /* Ditto */
}
/* Remember whether this is a variable length repeat */
@@ -4131,8 +4764,8 @@
op_type = 0; /* Default single-char op codes */
possessive_quantifier = FALSE; /* Default not possessive quantifier */
- /* Save start of previous item, in case we have to move it up to make space
- for an inserted OP_ONCE for the additional '+' extension. */
+ /* Save start of previous item, in case we have to move it up in order to
+ insert something before it. */
tempcode = previous;
@@ -4155,37 +4788,76 @@
}
else repeat_type = greedy_default;
- /* If previous was a character match, abolish the item and generate a
- repeat item instead. If a char item has a minumum of more than one, ensure
- that it is set in reqbyte - it might not be if a sequence such as x{3} is
- the first thing in a branch because the x will have gone into firstbyte
- instead. */
+ /* If previous was a recursion call, wrap it in atomic brackets so that
+ previous becomes the atomic group. All recursions were so wrapped in the
+ past, but it no longer happens for non-repeated recursions. In fact, the
+ repeated ones could be re-implemented independently so as not to need this,
+ but for the moment we rely on the code for repeating groups. */
- if (*previous == OP_CHAR || *previous == OP_CHARNC)
+ if (*previous == OP_RECURSE)
{
- /* Deal with UTF-8 characters that take up more than one byte. It's
+ memmove(previous + 1 + LINK_SIZE, previous, IN_UCHARS(1 + LINK_SIZE));
+ *previous = OP_ONCE;
+ PUT(previous, 1, 2 + 2*LINK_SIZE);
+ previous[2 + 2*LINK_SIZE] = OP_KET;
+ PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE);
+ code += 2 + 2 * LINK_SIZE;
+ length_prevgroup = 3 + 3*LINK_SIZE;
+
+ /* When actually compiling, we need to check whether this was a forward
+ reference, and if so, adjust the offset. */
+
+ if (lengthptr == NULL && cd->hwm >= cd->start_workspace + LINK_SIZE)
+ {
+ int offset = GET(cd->hwm, -LINK_SIZE);
+ if (offset == previous + 1 - cd->start_code)
+ PUT(cd->hwm, -LINK_SIZE, offset + 1 + LINK_SIZE);
+ }
+ }
+
+ /* Now handle repetition for the different types of item. */
+
+ /* If previous was a character or negated character match, abolish the item
+ and generate a repeat item instead. If a char item has a minimum of more
+ than one, ensure that it is set in reqchar - it might not be if a sequence
+ such as x{3} is the first thing in a branch because the x will have gone
+ into firstchar instead. */
+
+ if (*previous == OP_CHAR || *previous == OP_CHARI
+ || *previous == OP_NOT || *previous == OP_NOTI)
+ {
+ switch (*previous)
+ {
+ default: /* Make compiler happy. */
+ case OP_CHAR: op_type = OP_STAR - OP_STAR; break;
+ case OP_CHARI: op_type = OP_STARI - OP_STAR; break;
+ case OP_NOT: op_type = OP_NOTSTAR - OP_STAR; break;
+ case OP_NOTI: op_type = OP_NOTSTARI - OP_STAR; break;
+ }
+
+ /* Deal with UTF characters that take up more than one character. It's
easier to write this out separately than try to macrify it. Use c to
- hold the length of the character in bytes, plus 0x80 to flag that it's a
- length rather than a small character. */
+ hold the length of the character in bytes, plus UTF_LENGTH to flag that
+ it's a length rather than a small character. */
-#ifdef SUPPORT_UTF8
- if (utf8 && (code[-1] & 0x80) != 0)
+#ifdef SUPPORT_UTF
+ if (utf && NOT_FIRSTCHAR(code[-1]))
{
- uschar *lastchar = code - 1;
- while((*lastchar & 0xc0) == 0x80) lastchar--;
- c = code - lastchar; /* Length of UTF-8 character */
- memcpy(utf8_char, lastchar, c); /* Save the char */
- c |= 0x80; /* Flag c as a length */
+ pcre_uchar *lastchar = code - 1;
+ BACKCHAR(lastchar);
+ c = (int)(code - lastchar); /* Length of UTF-8 character */
+ memcpy(utf_chars, lastchar, IN_UCHARS(c)); /* Save the char */
+ c |= UTF_LENGTH; /* Flag c as a length */
}
else
-#endif
-
- /* Handle the case of a single byte - either with no UTF8 support, or
- with UTF-8 disabled, or for a UTF-8 character < 128. */
+#endif /* SUPPORT_UTF */
+ /* Handle the case of a single charater - either with no UTF support, or
+ with UTF disabled, or for a single character UTF character. */
{
c = code[-1];
- if (repeat_min > 1) reqbyte = c | req_caseopt | cd->req_varyopt;
+ if (*previous <= OP_CHARI && repeat_min > 1)
+ reqchar = c | req_caseopt | cd->req_varyopt;
}
/* If the repetition is unlimited, it pays to see if the next thing on
@@ -4195,7 +4867,7 @@
if (!possessive_quantifier &&
repeat_max < 0 &&
- check_auto_possessive(previous, utf8, ptr + 1, options, cd))
+ check_auto_possessive(previous, utf, ptr + 1, options, cd))
{
repeat_type = 0; /* Force greedy */
possessive_quantifier = TRUE;
@@ -4204,26 +4876,6 @@
goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */
}
- /* If previous was a single negated character ([^a] or similar), we use
- one of the special opcodes, replacing it. The code is shared with single-
- character repeats by setting opt_type to add a suitable offset into
- repeat_type. We can also test for auto-possessification. OP_NOT is
- currently used only for single-byte chars. */
-
- else if (*previous == OP_NOT)
- {
- op_type = OP_NOTSTAR - OP_STAR; /* Use "not" opcodes */
- c = previous[1];
- if (!possessive_quantifier &&
- repeat_max < 0 &&
- check_auto_possessive(previous, utf8, ptr + 1, options, cd))
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- }
- goto OUTPUT_SINGLE_REPEAT;
- }
-
/* If previous was a character type match (\d or similar), abolish it and
create a suitable repeat item. The code is shared with single-character
repeats by setting op_type to add a suitable offset into repeat_type. Note
@@ -4233,14 +4885,14 @@
else if (*previous < OP_EODN)
{
- uschar *oldcode;
+ pcre_uchar *oldcode;
int prop_type, prop_value;
op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */
c = *previous;
if (!possessive_quantifier &&
repeat_max < 0 &&
- check_auto_possessive(previous, utf8, ptr + 1, options, cd))
+ check_auto_possessive(previous, utf, ptr + 1, options, cd))
{
repeat_type = 0; /* Force greedy */
possessive_quantifier = TRUE;
@@ -4320,14 +4972,14 @@
we have to insert the character for the previous code. For a repeated
Unicode property match, there are two extra bytes that define the
required property. In UTF-8 mode, long characters have their length in
- c, with the 0x80 bit as a flag. */
+ c, with the UTF_LENGTH bit as a flag. */
if (repeat_max < 0)
{
-#ifdef SUPPORT_UTF8
- if (utf8 && c >= 128)
+#ifdef SUPPORT_UTF
+ if (utf && (c & UTF_LENGTH) != 0)
{
- memcpy(code, utf8_char, c & 7);
+ memcpy(code, utf_chars, IN_UCHARS(c & 7));
code += c & 7;
}
else
@@ -4349,10 +5001,10 @@
else if (repeat_max != repeat_min)
{
-#ifdef SUPPORT_UTF8
- if (utf8 && c >= 128)
+#ifdef SUPPORT_UTF
+ if (utf && (c & UTF_LENGTH) != 0)
{
- memcpy(code, utf8_char, c & 7);
+ memcpy(code, utf_chars, IN_UCHARS(c & 7));
code += c & 7;
}
else
@@ -4379,10 +5031,10 @@
/* The character or character type itself comes last in all cases. */
-#ifdef SUPPORT_UTF8
- if (utf8 && c >= 128)
+#ifdef SUPPORT_UTF
+ if (utf && (c & UTF_LENGTH) != 0)
{
- memcpy(code, utf8_char, c & 7);
+ memcpy(code, utf_chars, IN_UCHARS(c & 7));
code += c & 7;
}
else
@@ -4406,10 +5058,11 @@
else if (*previous == OP_CLASS ||
*previous == OP_NCLASS ||
-#ifdef SUPPORT_UTF8
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
*previous == OP_XCLASS ||
#endif
- *previous == OP_REF)
+ *previous == OP_REF ||
+ *previous == OP_REFI)
{
if (repeat_max == 0)
{
@@ -4443,35 +5096,35 @@
}
/* If previous was a bracket group, we may have to replicate it in certain
- cases. */
+ cases. Note that at this point we can encounter only the "basic" bracket
+ opcodes such as BRA and CBRA, as this is the place where they get converted
+ into the more special varieties such as BRAPOS and SBRA. A test for >=
+ OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK,
+ ASSERTBACK_NOT, ONCE, BRA, CBRA, and COND. Originally, PCRE did not allow
+ repetition of assertions, but now it does, for Perl compatibility. */
- else if (*previous == OP_BRA || *previous == OP_CBRA ||
- *previous == OP_ONCE || *previous == OP_COND)
+ else if (*previous >= OP_ASSERT && *previous <= OP_COND)
{
register int i;
- int ketoffset = 0;
int len = (int)(code - previous);
- uschar *bralink = NULL;
+ pcre_uchar *bralink = NULL;
+ pcre_uchar *brazeroptr = NULL;
- /* Repeating a DEFINE group is pointless */
+ /* Repeating a DEFINE group is pointless, but Perl allows the syntax, so
+ we just ignore the repeat. */
if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF)
- {
- *errorcodeptr = ERR55;
- goto FAILED;
- }
+ goto END_REPEAT;
+
+ /* There is no sense in actually repeating assertions. The only potential
+ use of repetition is in cases when the assertion is optional. Therefore,
+ if the minimum is greater than zero, just ignore the repeat. If the
+ maximum is not not zero or one, set it to 1. */
- /* If the maximum repeat count is unlimited, find the end of the bracket
- by scanning through from the start, and compute the offset back to it
- from the current code pointer. There may be an OP_OPT setting following
- the final KET, so we can't find the end just by going back from the code
- pointer. */
-
- if (repeat_max == -1)
- {
- register uschar *ket = previous;
- do ket += GET(ket, 1); while (*ket != OP_KET);
- ketoffset = (int)(code - ket);
+ if (*previous < OP_ONCE) /* Assertion */
+ {
+ if (repeat_min > 0) goto END_REPEAT;
+ if (repeat_max < 0 || repeat_max > 1) repeat_max = 1;
}
/* The case of a zero minimum is special because of the need to stick
@@ -4492,10 +5145,11 @@
** goto END_REPEAT;
** }
- However, that fails when a group is referenced as a subroutine from
- elsewhere in the pattern, so now we stick in OP_SKIPZERO in front of it
- so that it is skipped on execution. As we don't have a list of which
- groups are referenced, we cannot do this selectively.
+ However, that fails when a group or a subgroup within it is referenced
+ as a subroutine from elsewhere in the pattern, so now we stick in
+ OP_SKIPZERO in front of it so that it is skipped on execution. As we
+ don't have a list of which groups are referenced, we cannot do this
+ selectively.
If the maximum is 1 or unlimited, we just have to stick in the BRAZERO
and do no more at this point. However, we do need to adjust any
@@ -4507,14 +5161,15 @@
if (repeat_max <= 1) /* Covers 0, 1, and unlimited */
{
*code = OP_END;
- adjust_recurse(previous, 1, utf8, cd, save_hwm);
- memmove(previous+1, previous, len);
+ adjust_recurse(previous, 1, utf, cd, save_hwm);
+ memmove(previous + 1, previous, IN_UCHARS(len));
code++;
if (repeat_max == 0)
{
*previous++ = OP_SKIPZERO;
goto END_REPEAT;
}
+ brazeroptr = previous; /* Save for possessive optimizing */
*previous++ = OP_BRAZERO + repeat_type;
}
@@ -4530,8 +5185,8 @@
{
int offset;
*code = OP_END;
- adjust_recurse(previous, 2 + LINK_SIZE, utf8, cd, save_hwm);
- memmove(previous + 2 + LINK_SIZE, previous, len);
+ adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm);
+ memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
code += 2 + LINK_SIZE;
*previous++ = OP_BRAZERO + repeat_type;
*previous++ = OP_BRA;
@@ -4577,16 +5232,32 @@
*lengthptr += delta;
}
- /* This is compiling for real */
+ /* This is compiling for real. If there is a set first byte for
+ the group, and we have not yet set a "required byte", set it. Make
+ sure there is enough workspace for copying forward references before
+ doing the copy. */
else
{
- if (groupsetfirstbyte && reqbyte < 0) reqbyte = firstbyte;
+ if (groupsetfirstchar && reqchar < 0) reqchar = firstchar;
+
for (i = 1; i < repeat_min; i++)
{
- uschar *hc;
- uschar *this_hwm = cd->hwm;
- memcpy(code, previous, len);
+ pcre_uchar *hc;
+ pcre_uchar *this_hwm = cd->hwm;
+ memcpy(code, previous, IN_UCHARS(len));
+
+ while (cd->hwm > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
+ {
+ int save_offset = save_hwm - cd->start_workspace;
+ int this_offset = this_hwm - cd->start_workspace;
+ *errorcodeptr = expand_workspace(cd);
+ if (*errorcodeptr != 0) goto FAILED;
+ save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
+ this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
+ }
+
for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
{
PUT(cd->hwm, 0, GET(hc, 0) + len);
@@ -4636,8 +5307,8 @@
else for (i = repeat_max - 1; i >= 0; i--)
{
- uschar *hc;
- uschar *this_hwm = cd->hwm;
+ pcre_uchar *hc;
+ pcre_uchar *this_hwm = cd->hwm;
*code++ = OP_BRAZERO + repeat_type;
@@ -4653,7 +5324,22 @@
PUTINC(code, 0, offset);
}
- memcpy(code, previous, len);
+ memcpy(code, previous, IN_UCHARS(len));
+
+ /* Ensure there is enough workspace for forward references before
+ copying them. */
+
+ while (cd->hwm > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
+ {
+ int save_offset = save_hwm - cd->start_workspace;
+ int this_offset = this_hwm - cd->start_workspace;
+ *errorcodeptr = expand_workspace(cd);
+ if (*errorcodeptr != 0) goto FAILED;
+ save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
+ this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
+ }
+
for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
{
PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
@@ -4670,7 +5356,7 @@
{
int oldlinkoffset;
int offset = (int)(code - bralink + 1);
- uschar *bra = code - offset;
+ pcre_uchar *bra = code - offset;
oldlinkoffset = GET(bra, 1);
bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
*code++ = OP_KET;
@@ -4679,35 +5365,110 @@
}
}
- /* If the maximum is unlimited, set a repeater in the final copy. We
- can't just offset backwards from the current code point, because we
- don't know if there's been an options resetting after the ket. The
- correct offset was computed above.
+ /* If the maximum is unlimited, set a repeater in the final copy. For
+ ONCE brackets, that's all we need to do. However, possessively repeated
+ ONCE brackets can be converted into non-capturing brackets, as the
+ behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to
+ deal with possessive ONCEs specially.
- Then, when we are doing the actual compile phase, check to see whether
- this group is a non-atomic one that could match an empty string. If so,
+ Otherwise, when we are doing the actual compile phase, check to see
+ whether this group is one that could match an empty string. If so,
convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
- that runtime checking can be done. [This check is also applied to
- atomic groups at runtime, but in a different way.] */
+ that runtime checking can be done. [This check is also applied to ONCE
+ groups at runtime, but in a different way.]
+
+ Then, if the quantifier was possessive and the bracket is not a
+ conditional, we convert the BRA code to the POS form, and the KET code to
+ KETRPOS. (It turns out to be convenient at runtime to detect this kind of
+ subpattern at both the start and at the end.) The use of special opcodes
+ makes it possible to reduce greatly the stack usage in pcre_exec(). If
+ the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO.
+
+ Then, if the minimum number of matches is 1 or 0, cancel the possessive
+ flag so that the default action below, of wrapping everything inside
+ atomic brackets, does not happen. When the minimum is greater than 1,
+ there will be earlier copies of the group, and so we still have to wrap
+ the whole thing. */
else
{
- uschar *ketcode = code - ketoffset;
- uschar *bracode = ketcode - GET(ketcode, 1);
- *ketcode = OP_KETRMAX + repeat_type;
- if (lengthptr == NULL && *bracode != OP_ONCE)
+ pcre_uchar *ketcode = code - 1 - LINK_SIZE;
+ pcre_uchar *bracode = ketcode - GET(ketcode, 1);
+
+ /* Convert possessive ONCE brackets to non-capturing */
+
+ if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) &&
+ possessive_quantifier) *bracode = OP_BRA;
+
+ /* For non-possessive ONCE brackets, all we need to do is to
+ set the KET. */
+
+ if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC)
+ *ketcode = OP_KETRMAX + repeat_type;
+
+ /* Handle non-ONCE brackets and possessive ONCEs (which have been
+ converted to non-capturing above). */
+
+ else
{
- uschar *scode = bracode;
- do
+ /* In the compile phase, check for empty string matching. */
+
+ if (lengthptr == NULL)
{
- if (could_be_empty_branch(scode, ketcode, utf8, cd))
+ pcre_uchar *scode = bracode;
+ do
{
- *bracode += OP_SBRA - OP_BRA;
- break;
+ if (could_be_empty_branch(scode, ketcode, utf, cd))
+ {
+ *bracode += OP_SBRA - OP_BRA;
+ break;
+ }
+ scode += GET(scode, 1);
+ }
+ while (*scode == OP_ALT);
+ }
+
+ /* Handle possessive quantifiers. */
+
+ if (possessive_quantifier)
+ {
+ /* For COND brackets, we wrap the whole thing in a possessively
+ repeated non-capturing bracket, because we have not invented POS
+ versions of the COND opcodes. Because we are moving code along, we
+ must ensure that any pending recursive references are updated. */
+
+ if (*bracode == OP_COND || *bracode == OP_SCOND)
+ {
+ int nlen = (int)(code - bracode);
+ *code = OP_END;
+ adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm);
+ memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
+ code += 1 + LINK_SIZE;
+ nlen += 1 + LINK_SIZE;
+ *bracode = OP_BRAPOS;
+ *code++ = OP_KETRPOS;
+ PUTINC(code, 0, nlen);
+ PUT(bracode, 1, nlen);
}
- scode += GET(scode, 1);
+
+ /* For non-COND brackets, we modify the BRA code and use KETRPOS. */
+
+ else
+ {
+ *bracode += 1; /* Switch to xxxPOS opcodes */
+ *ketcode = OP_KETRPOS;
+ }
+
+ /* If the minimum is zero, mark it as possessive, then unset the
+ possessive flag when the minimum is 0 or 1. */
+
+ if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;
+ if (repeat_min < 2) possessive_quantifier = FALSE;
}
- while (*scode == OP_ALT);
+
+ /* Non-possessive quantifier */
+
+ else *ketcode = OP_KETRMAX + repeat_type;
}
}
}
@@ -4728,13 +5489,18 @@
}
/* If the character following a repeat is '+', or if certain optimization
- tests above succeeded, possessive_quantifier is TRUE. For some of the
- simpler opcodes, there is an special alternative opcode for this. For
- anything else, we wrap the entire repeated item inside OP_ONCE brackets.
- The '+' notation is just syntactic sugar, taken from Sun's Java package,
- but the special opcodes can optimize it a bit. The repeated item starts at
- tempcode, not at previous, which might be the first part of a string whose
- (former) last char we repeated.
+ tests above succeeded, possessive_quantifier is TRUE. For some opcodes,
+ there are special alternative opcodes for this case. For anything else, we
+ wrap the entire repeated item inside OP_ONCE brackets. Logically, the '+'
+ notation is just syntactic sugar, taken from Sun's Java package, but the
+ special opcodes can optimize it.
+
+ Some (but not all) possessively repeated subpatterns have already been
+ completely handled in the code just above. For them, possessive_quantifier
+ is always FALSE at this stage.
+
+ Note that the repeated item starts at tempcode, not at previous, which
+ might be the first part of a string whose (former) last char we repeated.
Possessifying an 'exact' quantifier has no effect, so we can ignore it. But
an 'upto' may follow. We skip over an 'exact' item, and then test the
@@ -4745,15 +5511,16 @@
int len;
if (*tempcode == OP_TYPEEXACT)
- tempcode += _pcre_OP_lengths[*tempcode] +
- ((tempcode[3] == OP_PROP || tempcode[3] == OP_NOTPROP)? 2 : 0);
+ tempcode += PRIV(OP_lengths)[*tempcode] +
+ ((tempcode[1 + IMM2_SIZE] == OP_PROP
+ || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT)
{
- tempcode += _pcre_OP_lengths[*tempcode];
-#ifdef SUPPORT_UTF8
- if (utf8 && tempcode[-1] >= 0xc0)
- tempcode += _pcre_utf8_table4[tempcode[-1] & 0x3f];
+ tempcode += PRIV(OP_lengths)[*tempcode];
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(tempcode[-1]))
+ tempcode += GET_EXTRALEN(tempcode[-1]);
#endif
}
@@ -4765,23 +5532,33 @@
case OP_QUERY: *tempcode = OP_POSQUERY; break;
case OP_UPTO: *tempcode = OP_POSUPTO; break;
- case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break;
- case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break;
- case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break;
- case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break;
+ case OP_STARI: *tempcode = OP_POSSTARI; break;
+ case OP_PLUSI: *tempcode = OP_POSPLUSI; break;
+ case OP_QUERYI: *tempcode = OP_POSQUERYI; break;
+ case OP_UPTOI: *tempcode = OP_POSUPTOI; break;
case OP_NOTSTAR: *tempcode = OP_NOTPOSSTAR; break;
case OP_NOTPLUS: *tempcode = OP_NOTPOSPLUS; break;
case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break;
case OP_NOTUPTO: *tempcode = OP_NOTPOSUPTO; break;
+ case OP_NOTSTARI: *tempcode = OP_NOTPOSSTARI; break;
+ case OP_NOTPLUSI: *tempcode = OP_NOTPOSPLUSI; break;
+ case OP_NOTQUERYI: *tempcode = OP_NOTPOSQUERYI; break;
+ case OP_NOTUPTOI: *tempcode = OP_NOTPOSUPTOI; break;
+
+ case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break;
+ case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break;
+ case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break;
+ case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break;
+
/* Because we are moving code along, we must ensure that any
pending recursive references are updated. */
default:
*code = OP_END;
- adjust_recurse(tempcode, 1 + LINK_SIZE, utf8, cd, save_hwm);
- memmove(tempcode + 1+LINK_SIZE, tempcode, len);
+ adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
+ memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
code += 1 + LINK_SIZE;
len += 1 + LINK_SIZE;
tempcode[0] = OP_ONCE;
@@ -4793,7 +5570,7 @@
}
/* In all case we no longer have a previous item. We also set the
- "follows varying string" flag for subsequently encountered reqbytes if
+ "follows varying string" flag for subsequently encountered reqchars if
it isn't already set and we have just passed a varying length item. */
END_REPEAT:
@@ -4816,24 +5593,34 @@
/* First deal with various "verbs" that can be introduced by '*'. */
- if (*(++ptr) == CHAR_ASTERISK &&
- ((cd->ctypes[ptr[1]] & ctype_letter) != 0 || ptr[1] == ':'))
+ ptr++;
+ if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':'
+ || (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0))))
{
int i, namelen;
int arglen = 0;
const char *vn = verbnames;
- const uschar *name = ptr + 1;
- const uschar *arg = NULL;
+ const pcre_uchar *name = ptr + 1;
+ const pcre_uchar *arg = NULL;
previous = NULL;
- while ((cd->ctypes[*++ptr] & ctype_letter) != 0) {};
+ ptr++;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_letter) != 0) ptr++;
namelen = (int)(ptr - name);
+ /* It appears that Perl allows any characters whatsoever, other than
+ a closing parenthesis, to appear in arguments, so we no longer insist on
+ letters, digits, and underscores. */
+
if (*ptr == CHAR_COLON)
{
arg = ++ptr;
- while ((cd->ctypes[*ptr] & (ctype_letter|ctype_digit)) != 0
- || *ptr == '_') ptr++;
+ while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
arglen = (int)(ptr - arg);
+ if (arglen > (int)MAX_MARK)
+ {
+ *errorcodeptr = ERR75;
+ goto FAILED;
+ }
}
if (*ptr != CHAR_RIGHT_PARENTHESIS)
@@ -4847,24 +5634,34 @@
for (i = 0; i < verbcount; i++)
{
if (namelen == verbs[i].len &&
- strncmp((char *)name, vn, namelen) == 0)
+ STRNCMP_UC_C8(name, vn, namelen) == 0)
{
- /* Check for open captures before ACCEPT */
+ /* Check for open captures before ACCEPT and convert it to
+ ASSERT_ACCEPT if in an assertion. */
if (verbs[i].op == OP_ACCEPT)
{
open_capitem *oc;
+ if (arglen != 0)
+ {
+ *errorcodeptr = ERR59;
+ goto FAILED;
+ }
cd->had_accept = TRUE;
for (oc = cd->open_caps; oc != NULL; oc = oc->next)
{
*code++ = OP_CLOSE;
PUT2INC(code, 0, oc->number);
}
+ *code++ = (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT;
+
+ /* Do not set firstchar after *ACCEPT */
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
}
- /* Handle the cases with/without an argument */
+ /* Handle other cases with/without an argument */
- if (arglen == 0)
+ else if (arglen == 0)
{
if (verbs[i].op < 0) /* Argument is mandatory */
{
@@ -4872,11 +5669,7 @@
goto FAILED;
}
*code = verbs[i].op;
- if (*code++ == OP_THEN)
- {
- PUT(code, 0, code - bcptr->current_branch - 1);
- code += LINK_SIZE;
- }
+ if (*code++ == OP_THEN) cd->external_flags |= PCRE_HASTHEN;
}
else
@@ -4887,13 +5680,9 @@
goto FAILED;
}
*code = verbs[i].op_arg;
- if (*code++ == OP_THEN_ARG)
- {
- PUT(code, 0, code - bcptr->current_branch - 1);
- code += LINK_SIZE;
- }
+ if (*code++ == OP_THEN_ARG) cd->external_flags |= PCRE_HASTHEN;
*code++ = arglen;
- memcpy(code, arg, arglen);
+ memcpy(code, arg, IN_UCHARS(arglen));
code += arglen;
*code++ = 0;
}
@@ -4916,8 +5705,8 @@
{
int i, set, unset, namelen;
int *optset;
- const uschar *name;
- uschar *slot;
+ const pcre_uchar *name;
+ pcre_uchar *slot;
switch (*(++ptr))
{
@@ -4970,10 +5759,10 @@
break;
/* Most other conditions use OP_CREF (a couple change to OP_RREF
- below), and all need to skip 3 bytes at the start of the group. */
+ below), and all need to skip 1+IMM2_SIZE bytes at the start of the group. */
code[1+LINK_SIZE] = OP_CREF;
- skipbytes = 3;
+ skipbytes = 1+IMM2_SIZE;
refsign = -1;
/* Check for a test for recursion in a named group. */
@@ -5006,7 +5795,7 @@
/* We now expect to read a name; any thing else is an error */
- if ((cd->ctypes[ptr[1]] & ctype_word) == 0)
+ if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0)
{
ptr += 1; /* To get the right offset */
*errorcodeptr = ERR28;
@@ -5017,11 +5806,10 @@
recno = 0;
name = ++ptr;
- while ((cd->ctypes[*ptr] & ctype_word) != 0)
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0)
{
if (recno >= 0)
- recno = ((digitab[*ptr] & ctype_digit) != 0)?
- recno * 10 + *ptr - CHAR_0 : -1;
+ recno = (IS_DIGIT(*ptr))? recno * 10 + *ptr - CHAR_0 : -1;
ptr++;
}
namelen = (int)(ptr - name);
@@ -5069,7 +5857,7 @@
slot = cd->name_table;
for (i = 0; i < cd->names_found; i++)
{
- if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break;
+ if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0) break;
slot += cd->name_entry_size;
}
@@ -5085,7 +5873,7 @@
/* Search the pattern for a forward reference */
else if ((i = find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf8)) > 0)
+ (options & PCRE_EXTENDED) != 0, utf)) > 0)
{
PUT2(code, 2+LINK_SIZE, i);
code[1+LINK_SIZE]++;
@@ -5111,7 +5899,7 @@
recno = 0;
for (i = 1; i < namelen; i++)
{
- if ((digitab[name[i]] & ctype_digit) == 0)
+ if (!IS_DIGIT(name[i]))
{
*errorcodeptr = ERR15;
goto FAILED;
@@ -5126,7 +5914,7 @@
/* Similarly, check for the (?(DEFINE) "condition", which is always
false. */
- else if (namelen == 6 && strncmp((char *)name, STRING_DEFINE, 6) == 0)
+ else if (namelen == 6 && STRNCMP_UC_C8(name, STRING_DEFINE, 6) == 0)
{
code[1+LINK_SIZE] = OP_DEF;
skipbytes = 1;
@@ -5153,6 +5941,7 @@
/* ------------------------------------------------------------ */
case CHAR_EQUALS_SIGN: /* Positive lookahead */
bravalue = OP_ASSERT;
+ cd->assert_depth += 1;
ptr++;
break;
@@ -5167,6 +5956,7 @@
continue;
}
bravalue = OP_ASSERT_NOT;
+ cd->assert_depth += 1;
break;
@@ -5176,16 +5966,19 @@
{
case CHAR_EQUALS_SIGN: /* Positive lookbehind */
bravalue = OP_ASSERTBACK;
+ cd->assert_depth += 1;
ptr += 2;
break;
case CHAR_EXCLAMATION_MARK: /* Negative lookbehind */
bravalue = OP_ASSERTBACK_NOT;
+ cd->assert_depth += 1;
ptr += 2;
break;
default: /* Could be name define, else bad */
- if ((cd->ctypes[ptr[1]] & ctype_word) != 0) goto DEFINE_NAME;
+ if (MAX_255(ptr[1]) && (cd->ctypes[ptr[1]] & ctype_word) != 0)
+ goto DEFINE_NAME;
ptr++; /* Correct offset for error */
*errorcodeptr = ERR24;
goto FAILED;
@@ -5202,13 +5995,14 @@
/* ------------------------------------------------------------ */
case CHAR_C: /* Callout - may be followed by digits; */
- previous_callout = code; /* Save for later completion */
- after_manual_callout = 1; /* Skip one item before completing */
+ previous_callout = code; /* Save for later completion */
+ after_manual_callout = 1; /* Skip one item before completing */
*code++ = OP_CALLOUT;
{
int n = 0;
- while ((digitab[*(++ptr)] & ctype_digit) != 0)
- n = n * 10 + *ptr - CHAR_0;
+ ptr++;
+ while(IS_DIGIT(*ptr))
+ n = n * 10 + *ptr++ - CHAR_0;
if (*ptr != CHAR_RIGHT_PARENTHESIS)
{
*errorcodeptr = ERR39;
@@ -5253,7 +6047,7 @@
CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
name = ++ptr;
- while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
namelen = (int)(ptr - name);
/* In the pre-compile phase, just do a syntax check. */
@@ -5270,9 +6064,9 @@
*errorcodeptr = ERR49;
goto FAILED;
}
- if (namelen + 3 > cd->name_entry_size)
+ if (namelen + IMM2_SIZE + 1 > cd->name_entry_size)
{
- cd->name_entry_size = namelen + 3;
+ cd->name_entry_size = namelen + IMM2_SIZE + 1;
if (namelen > MAX_NAME_SIZE)
{
*errorcodeptr = ERR48;
@@ -5301,10 +6095,10 @@
for (i = 0; i < cd->names_found; i++)
{
- int crc = memcmp(name, slot+2, namelen);
+ int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(namelen));
if (crc == 0)
{
- if (slot[2+namelen] == 0)
+ if (slot[IMM2_SIZE+namelen] == 0)
{
if (GET2(slot, 0) != cd->bracount + 1 &&
(options & PCRE_DUPNAMES) == 0)
@@ -5325,7 +6119,7 @@
if (crc < 0)
{
memmove(slot + cd->name_entry_size, slot,
- (cd->names_found - i) * cd->name_entry_size);
+ IN_UCHARS((cd->names_found - i) * cd->name_entry_size));
break;
}
@@ -5339,7 +6133,7 @@
if (!dupname)
{
- uschar *cslot = cd->name_table;
+ pcre_uchar *cslot = cd->name_table;
for (i = 0; i < cd->names_found; i++)
{
if (cslot != slot)
@@ -5356,8 +6150,8 @@
}
PUT2(slot, 0, cd->bracount + 1);
- memcpy(slot + 2, name, namelen);
- slot[2+namelen] = 0;
+ memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen));
+ slot[IMM2_SIZE + namelen] = 0;
}
}
@@ -5383,7 +6177,7 @@
NAMED_REF_OR_RECURSE:
name = ++ptr;
- while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
namelen = (int)(ptr - name);
/* In the pre-compile phase, do a syntax check. We used to just set
@@ -5395,7 +6189,7 @@
if (lengthptr != NULL)
{
- const uschar *temp;
+ const pcre_uchar *temp;
if (namelen == 0)
{
@@ -5425,7 +6219,7 @@
temp = cd->end_pattern;
cd->end_pattern = ptr;
recno = find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf8);
+ (options & PCRE_EXTENDED) != 0, utf);
cd->end_pattern = temp;
if (recno < 0) recno = 0; /* Forward ref; set dummy number */
}
@@ -5440,8 +6234,8 @@
slot = cd->name_table;
for (i = 0; i < cd->names_found; i++)
{
- if (strncmp((char *)name, (char *)slot+2, namelen) == 0 &&
- slot[2+namelen] == 0)
+ if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0 &&
+ slot[IMM2_SIZE+namelen] == 0)
break;
slot += cd->name_entry_size;
}
@@ -5452,7 +6246,7 @@
}
else if ((recno = /* Forward back reference */
find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf8)) <= 0)
+ (options & PCRE_EXTENDED) != 0, utf)) <= 0)
{
*errorcodeptr = ERR15;
goto FAILED;
@@ -5477,7 +6271,7 @@
case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4:
case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
{
- const uschar *called;
+ const pcre_uchar *called;
terminator = CHAR_RIGHT_PARENTHESIS;
/* Come here from the \g<...> and \g'...' code (Oniguruma
@@ -5491,7 +6285,7 @@
if ((refsign = *ptr) == CHAR_PLUS)
{
ptr++;
- if ((digitab[*ptr] & ctype_digit) == 0)
+ if (!IS_DIGIT(*ptr))
{
*errorcodeptr = ERR63;
goto FAILED;
@@ -5499,13 +6293,13 @@
}
else if (refsign == CHAR_MINUS)
{
- if ((digitab[ptr[1]] & ctype_digit) == 0)
+ if (!IS_DIGIT(ptr[1]))
goto OTHER_CHAR_AFTER_QUERY;
ptr++;
}
recno = 0;
- while((digitab[*ptr] & ctype_digit) != 0)
+ while(IS_DIGIT(*ptr))
recno = recno * 10 + *ptr++ - CHAR_0;
if (*ptr != terminator)
@@ -5556,14 +6350,14 @@
{
*code = OP_END;
if (recno != 0)
- called = _pcre_find_bracket(cd->start_code, utf8, recno);
+ called = PRIV(find_bracket)(cd->start_code, utf, recno);
/* Forward reference */
if (called == NULL)
{
if (find_parens(cd, NULL, recno,
- (options & PCRE_EXTENDED) != 0, utf8) < 0)
+ (options & PCRE_EXTENDED) != 0, utf) < 0)
{
*errorcodeptr = ERR15;
goto FAILED;
@@ -5571,46 +6365,48 @@
/* Fudge the value of "called" so that when it is inserted as an
offset below, what it actually inserted is the reference number
- of the group. */
+ of the group. Then remember the forward reference. */
called = cd->start_code + recno;
- PUTINC(cd->hwm, 0, (int)(code + 2 + LINK_SIZE - cd->start_code));
+ if (cd->hwm >= cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN)
+ {
+ *errorcodeptr = expand_workspace(cd);
+ if (*errorcodeptr != 0) goto FAILED;
+ }
+ PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code));
}
/* If not a forward reference, and the subpattern is still open,
this is a recursive call. We check to see if this is a left
- recursion that could loop for ever, and diagnose that case. */
+ recursion that could loop for ever, and diagnose that case. We
+ must not, however, do this check if we are in a conditional
+ subpattern because the condition might be testing for recursion in
+ a pattern such as /(?(R)a+|(?R)b)/, which is perfectly valid.
+ Forever loops are also detected at runtime, so those that occur in
+ conditional subpatterns will be picked up then. */
- else if (GET(called, 1) == 0 &&
- could_be_empty(called, code, bcptr, utf8, cd))
+ else if (GET(called, 1) == 0 && cond_depth <= 0 &&
+ could_be_empty(called, code, bcptr, utf, cd))
{
*errorcodeptr = ERR40;
goto FAILED;
}
}
- /* Insert the recursion/subroutine item, automatically wrapped inside
- "once" brackets. Set up a "previous group" length so that a
- subsequent quantifier will work. */
-
- *code = OP_ONCE;
- PUT(code, 1, 2 + 2*LINK_SIZE);
- code += 1 + LINK_SIZE;
+ /* Insert the recursion/subroutine item. It does not have a set first
+ character (relevant if it is repeated, because it will then be
+ wrapped with ONCE brackets). */
*code = OP_RECURSE;
PUT(code, 1, (int)(called - cd->start_code));
code += 1 + LINK_SIZE;
-
- *code = OP_KET;
- PUT(code, 1, 2 + 2*LINK_SIZE);
- code += 1 + LINK_SIZE;
-
- length_prevgroup = 3 + 3*LINK_SIZE;
+ groupsetfirstchar = FALSE;
}
/* Can't determine a first byte now */
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
continue;
@@ -5666,9 +6462,8 @@
is necessary to ensure we correctly detect the start of the pattern in
both phases.
- If we are not at the pattern start, compile code to change the ims
- options if this setting actually changes any of them, and reset the
- greedy defaults and the case value for firstbyte and reqbyte. */
+ If we are not at the pattern start, reset the greedy defaults and the
+ case value for firstchar and reqchar. */
if (*ptr == CHAR_RIGHT_PARENTHESIS)
{
@@ -5679,20 +6474,13 @@
}
else
{
- if ((options & PCRE_IMS) != (newoptions & PCRE_IMS))
- {
- *code++ = OP_OPT;
- *code++ = newoptions & PCRE_IMS;
- }
greedy_default = ((newoptions & PCRE_UNGREEDY) != 0);
greedy_non_default = greedy_default ^ 1;
- req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS : 0;
+ req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0;
}
/* Change options at this level, and pass them back for use
- in subsequent branches. When not at the start of the pattern, this
- information is also necessary so that a resetting item can be
- compiled at the end of a group (if we are in a group). */
+ in subsequent branches. */
*optionsptr = options = newoptions;
previous = NULL; /* This item can't be repeated */
@@ -5725,53 +6513,62 @@
NUMBERED_GROUP:
cd->bracount += 1;
PUT2(code, 1+LINK_SIZE, cd->bracount);
- skipbytes = 2;
+ skipbytes = IMM2_SIZE;
}
- /* Process nested bracketed regex. Assertions may not be repeated, but
- other kinds can be. All their opcodes are >= OP_ONCE. We copy code into a
- non-register variable in order to be able to pass its address because some
- compilers complain otherwise. Pass in a new setting for the ims options if
- they have changed. */
+ /* Process nested bracketed regex. Assertions used not to be repeatable,
+ but this was changed for Perl compatibility, so all kinds can now be
+ repeated. We copy code into a non-register variable (tempcode) in order to
+ be able to pass its address because some compilers complain otherwise. */
- previous = (bravalue >= OP_ONCE)? code : NULL;
+ previous = code; /* For handling repetition */
*code = bravalue;
tempcode = code;
- tempreqvary = cd->req_varyopt; /* Save value before bracket */
- length_prevgroup = 0; /* Initialize for pre-compile phase */
+ tempreqvary = cd->req_varyopt; /* Save value before bracket */
+ tempbracount = cd->bracount; /* Save value before bracket */
+ length_prevgroup = 0; /* Initialize for pre-compile phase */
if (!compile_regex(
- newoptions, /* The complete new option state */
- options & PCRE_IMS, /* The previous ims option state */
- &tempcode, /* Where to put code (updated) */
- &ptr, /* Input pointer (updated) */
- errorcodeptr, /* Where to put an error message */
+ newoptions, /* The complete new option state */
+ &tempcode, /* Where to put code (updated) */
+ &ptr, /* Input pointer (updated) */
+ errorcodeptr, /* Where to put an error message */
(bravalue == OP_ASSERTBACK ||
bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
- reset_bracount, /* True if (?| group */
- skipbytes, /* Skip over bracket number */
- &subfirstbyte, /* For possible first char */
- &subreqbyte, /* For possible last char */
- bcptr, /* Current branch chain */
- cd, /* Tables block */
- (lengthptr == NULL)? NULL : /* Actual compile phase */
- &length_prevgroup /* Pre-compile phase */
+ reset_bracount, /* True if (?| group */
+ skipbytes, /* Skip over bracket number */
+ cond_depth +
+ ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */
+ &subfirstchar, /* For possible first char */
+ &subreqchar, /* For possible last char */
+ bcptr, /* Current branch chain */
+ cd, /* Tables block */
+ (lengthptr == NULL)? NULL : /* Actual compile phase */
+ &length_prevgroup /* Pre-compile phase */
))
goto FAILED;
+ /* If this was an atomic group and there are no capturing groups within it,
+ generate OP_ONCE_NC instead of OP_ONCE. */
+
+ if (bravalue == OP_ONCE && cd->bracount <= tempbracount)
+ *code = OP_ONCE_NC;
+
+ if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT)
+ cd->assert_depth -= 1;
+
/* At the end of compiling, code is still pointing to the start of the
- group, while tempcode has been updated to point past the end of the group
- and any option resetting that may follow it. The pattern pointer (ptr)
- is on the bracket. */
+ group, while tempcode has been updated to point past the end of the group.
+ The pattern pointer (ptr) is on the bracket.
- /* If this is a conditional bracket, check that there are no more than
+ If this is a conditional bracket, check that there are no more than
two branches in the group, or just one if it's a DEFINE group. We do this
in the real compile phase, not in the pre-pass, where the whole group may
not be available. */
if (bravalue == OP_COND && lengthptr == NULL)
{
- uschar *tc = code;
+ pcre_uchar *tc = code;
int condcount = 0;
do {
@@ -5794,7 +6591,7 @@
}
/* A "normal" conditional group. If there is just one branch, we must not
- make use of its firstbyte or reqbyte, because this is equivalent to an
+ make use of its firstchar or reqchar, because this is equivalent to an
empty second branch. */
else
@@ -5804,7 +6601,7 @@
*errorcodeptr = ERR27;
goto FAILED;
}
- if (condcount == 1) subfirstbyte = subreqbyte = REQ_NONE;
+ if (condcount == 1) subfirstchar = subreqchar = REQ_NONE;
}
}
@@ -5829,7 +6626,7 @@
goto FAILED;
}
*lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
- *code++ = OP_BRA;
+ code++; /* This already contains bravalue */
PUTINC(code, 0, 1 + LINK_SIZE);
*code++ = OP_KET;
PUTINC(code, 0, 1 + LINK_SIZE);
@@ -5848,55 +6645,55 @@
/* Handle updating of the required and first characters for other types of
group. Update for normal brackets of all kinds, and conditions with two
branches (see code above). If the bracket is followed by a quantifier with
- zero repeat, we have to back off. Hence the definition of zeroreqbyte and
- zerofirstbyte outside the main loop so that they can be accessed for the
+ zero repeat, we have to back off. Hence the definition of zeroreqchar and
+ zerofirstchar outside the main loop so that they can be accessed for the
back off. */
- zeroreqbyte = reqbyte;
- zerofirstbyte = firstbyte;
- groupsetfirstbyte = FALSE;
+ zeroreqchar = reqchar;
+ zerofirstchar = firstchar;
+ groupsetfirstchar = FALSE;
if (bravalue >= OP_ONCE)
{
- /* If we have not yet set a firstbyte in this branch, take it from the
+ /* If we have not yet set a firstchar in this branch, take it from the
subpattern, remembering that it was set here so that a repeat of more
- than one can replicate it as reqbyte if necessary. If the subpattern has
- no firstbyte, set "none" for the whole branch. In both cases, a zero
- repeat forces firstbyte to "none". */
+ than one can replicate it as reqchar if necessary. If the subpattern has
+ no firstchar, set "none" for the whole branch. In both cases, a zero
+ repeat forces firstchar to "none". */
- if (firstbyte == REQ_UNSET)
+ if (firstchar == REQ_UNSET)
{
- if (subfirstbyte >= 0)
+ if (subfirstchar >= 0)
{
- firstbyte = subfirstbyte;
- groupsetfirstbyte = TRUE;
+ firstchar = subfirstchar;
+ groupsetfirstchar = TRUE;
}
- else firstbyte = REQ_NONE;
- zerofirstbyte = REQ_NONE;
+ else firstchar = REQ_NONE;
+ zerofirstchar = REQ_NONE;
}
- /* If firstbyte was previously set, convert the subpattern's firstbyte
- into reqbyte if there wasn't one, using the vary flag that was in
+ /* If firstchar was previously set, convert the subpattern's firstchar
+ into reqchar if there wasn't one, using the vary flag that was in
existence beforehand. */
- else if (subfirstbyte >= 0 && subreqbyte < 0)
- subreqbyte = subfirstbyte | tempreqvary;
+ else if (subfirstchar >= 0 && subreqchar < 0)
+ subreqchar = subfirstchar | tempreqvary;
/* If the subpattern set a required byte (or set a first byte that isn't
really the first byte - see above), set it. */
- if (subreqbyte >= 0) reqbyte = subreqbyte;
+ if (subreqchar >= 0) reqchar = subreqchar;
}
- /* For a forward assertion, we take the reqbyte, if set. This can be
+ /* For a forward assertion, we take the reqchar, if set. This can be
helpful if the pattern that follows the assertion doesn't set a different
- char. For example, it's useful for /(?=abcde).+/. We can't set firstbyte
+ char. For example, it's useful for /(?=abcde).+/. We can't set firstchar
for an assertion, however because it leads to incorrect effect for patterns
- such as /(?=a)a.+/ when the "real" "a" would then become a reqbyte instead
- of a firstbyte. This is overcome by a scan at the end if there's no
- firstbyte, looking for an asserted first char. */
+ such as /(?=a)a.+/ when the "real" "a" would then become a reqchar instead
+ of a firstchar. This is overcome by a scan at the end if there's no
+ firstchar, looking for an asserted first char. */
- else if (bravalue == OP_ASSERT && subreqbyte >= 0) reqbyte = subreqbyte;
+ else if (bravalue == OP_ASSERT && subreqchar >= 0) reqchar = subreqchar;
break; /* End of processing '(' */
@@ -5929,13 +6726,13 @@
/* For metasequences that actually match a character, we disable the
setting of a first character if it hasn't already been set. */
- if (firstbyte == REQ_UNSET && -c > ESC_b && -c < ESC_Z)
- firstbyte = REQ_NONE;
+ if (firstchar == REQ_UNSET && -c > ESC_b && -c < ESC_Z)
+ firstchar = REQ_NONE;
/* Set values to reset to if this is followed by a zero repeat. */
- zerofirstbyte = firstbyte;
- zeroreqbyte = reqbyte;
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
/* \g or \g'name' is a subroutine call by name and \g or \g'n'
is a subroutine call by number (Oniguruma syntax). In fact, the value
@@ -5946,7 +6743,7 @@
if (-c == ESC_g)
{
- const uschar *p;
+ const pcre_uchar *p;
save_hwm = cd->hwm; /* Normally this is set when '(' is read */
terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
@@ -5963,10 +6760,11 @@
if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS)
{
- BOOL isnumber = TRUE;
+ BOOL is_a_number = TRUE;
for (p = ptr + 1; *p != 0 && *p != terminator; p++)
{
- if ((cd->ctypes[*p] & ctype_digit) == 0) isnumber = FALSE;
+ if (!MAX_255(*p)) { is_a_number = FALSE; break; }
+ if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE;
if ((cd->ctypes[*p] & ctype_word) == 0) break;
}
if (*p != terminator)
@@ -5974,7 +6772,7 @@
*errorcodeptr = ERR57;
break;
}
- if (isnumber)
+ if (is_a_number)
{
ptr++;
goto HANDLE_NUMERICAL_RECURSION;
@@ -5986,7 +6784,7 @@
/* Test a signed number in angle brackets or quotes. */
p = ptr + 2;
- while ((digitab[*p] & ctype_digit) != 0) p++;
+ while (IS_DIGIT(*p)) p++;
if (*p != terminator)
{
*errorcodeptr = ERR57;
@@ -5997,11 +6795,16 @@
}
/* \k or \k'name' is a back reference by name (Perl syntax).
- We also support \k{name} (.NET syntax) */
+ We also support \k{name} (.NET syntax). */
- if (-c == ESC_k && (ptr[1] == CHAR_LESS_THAN_SIGN ||
- ptr[1] == CHAR_APOSTROPHE || ptr[1] == CHAR_LEFT_CURLY_BRACKET))
+ if (-c == ESC_k)
{
+ if ((ptr[1] != CHAR_LESS_THAN_SIGN &&
+ ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET))
+ {
+ *errorcodeptr = ERR69;
+ break;
+ }
is_recurse = FALSE;
terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?
@@ -6009,7 +6812,7 @@
goto NAMED_REF_OR_RECURSE;
}
- /* Back references are handled specially; must disable firstbyte if
+ /* Back references are handled specially; must disable firstchar if
not set to cope with cases like (?=(\w+))\1: which would otherwise set
':' later. */
@@ -6019,9 +6822,9 @@
recno = -c - ESC_REF;
HANDLE_REFERENCE: /* Come here from named backref handling */
- if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
previous = code;
- *code++ = OP_REF;
+ *code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
PUT2INC(code, 0, recno);
cd->backref_map |= (recno < 32)? (1 << recno) : 1;
if (recno > cd->top_backref) cd->top_backref = recno;
@@ -6069,10 +6872,13 @@
/* For the rest (including \X when Unicode properties are supported), we
can obtain the OP value by negating the escape value in the default
situation when PCRE_UCP is not set. When it *is* set, we substitute
- Unicode property tests. */
+ Unicode property tests. Note that \b and \B do a one-character
+ lookbehind. */
else
{
+ if ((-c == ESC_b || -c == ESC_B) && cd->max_lookbehind == 0)
+ cd->max_lookbehind = 1;
#ifdef SUPPORT_UCP
if (-c >= ESC_DU && -c <= ESC_wu)
{
@@ -6081,9 +6887,12 @@
}
else
#endif
+ /* In non-UTF-8 mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE
+ so that it works in DFA mode and in lookbehinds. */
+
{
previous = (-c > ESC_b && -c < ESC_Z)? code : NULL;
- *code++ = -c;
+ *code++ = (!utf && c == -ESC_C)? OP_ALLANY : -c;
}
}
continue;
@@ -6093,9 +6902,9 @@
a value > 127. We set its representation in the length/buffer, and then
handle it as a data character. */
-#ifdef SUPPORT_UTF8
- if (utf8 && c > 127)
- mclength = _pcre_ord2utf8(c, mcbuffer);
+#ifdef SUPPORT_UTF
+ if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
+ mclength = PRIV(ord2utf)(c, mcbuffer);
else
#endif
@@ -6116,12 +6925,9 @@
mclength = 1;
mcbuffer[0] = c;
-#ifdef SUPPORT_UTF8
- if (utf8 && c >= 0xc0)
- {
- while ((ptr[1] & 0xc0) == 0x80)
- mcbuffer[mclength++] = *(++ptr);
- }
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(c))
+ ACROSSCHAR(TRUE, ptr[1], mcbuffer[mclength++] = *(++ptr));
#endif
/* At this point we have the character's bytes in mcbuffer, and the length
@@ -6129,7 +6935,7 @@
ONE_CHAR:
previous = code;
- *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARNC : OP_CHAR;
+ *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARI : OP_CHAR;
for (c = 0; c < mclength; c++) *code++ = mcbuffer[c];
/* Remember if \r or \n were seen */
@@ -6139,34 +6945,34 @@
/* Set the first and required bytes appropriately. If no previous first
byte, set it from this character, but revert to none on a zero repeat.
- Otherwise, leave the firstbyte value alone, and don't change it on a zero
+ Otherwise, leave the firstchar value alone, and don't change it on a zero
repeat. */
- if (firstbyte == REQ_UNSET)
+ if (firstchar == REQ_UNSET)
{
- zerofirstbyte = REQ_NONE;
- zeroreqbyte = reqbyte;
+ zerofirstchar = REQ_NONE;
+ zeroreqchar = reqchar;
- /* If the character is more than one byte long, we can set firstbyte
+ /* If the character is more than one byte long, we can set firstchar
only if it is not to be matched caselessly. */
if (mclength == 1 || req_caseopt == 0)
{
- firstbyte = mcbuffer[0] | req_caseopt;
- if (mclength != 1) reqbyte = code[-1] | cd->req_varyopt;
+ firstchar = mcbuffer[0] | req_caseopt;
+ if (mclength != 1) reqchar = code[-1] | cd->req_varyopt;
}
- else firstbyte = reqbyte = REQ_NONE;
+ else firstchar = reqchar = REQ_NONE;
}
- /* firstbyte was previously set; we can set reqbyte only the length is
+ /* firstchar was previously set; we can set reqchar only if the length is
1 or the matching is caseful. */
else
{
- zerofirstbyte = firstbyte;
- zeroreqbyte = reqbyte;
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
if (mclength == 1 || req_caseopt == 0)
- reqbyte = code[-1] | req_caseopt | cd->req_varyopt;
+ reqchar = code[-1] | req_caseopt | cd->req_varyopt;
}
break; /* End of literal character handling */
@@ -6193,26 +6999,21 @@
/* On entry, ptr is pointing past the bracket character, but on return it
points to the closing bracket, or vertical bar, or end of string. The code
variable is pointing at the byte into which the BRA operator has been stored.
-If the ims options are changed at the start (for a (?ims: group) or during any
-branch, we need to insert an OP_OPT item at the start of every following branch
-to ensure they get set correctly at run time, and also pass the new options
-into every subsequent branch compile.
-
This function is used during the pre-compile phase when we are trying to find
out the amount of memory needed, as well as during the real compile phase. The
value of lengthptr distinguishes the two phases.
Arguments:
options option bits, including any changes for this subpattern
- oldims previous settings of ims option bits
codeptr -> the address of the current code pointer
ptrptr -> the address of the current pattern pointer
errorcodeptr -> pointer to error code variable
lookbehind TRUE if this is a lookbehind assertion
reset_bracount TRUE to reset the count for each branch
skipbytes skip this many bytes at start (for brackets and OP_COND)
- firstbyteptr place to put the first required character, or a negative number
- reqbyteptr place to put the last required character, or a negative number
+ cond_depth depth of nesting for conditional subpatterns
+ firstcharptr place to put the first required character, or a negative number
+ reqcharptr place to put the last required character, or a negative number
bcptr pointer to the chain of currently open branches
cd points to the data block with tables pointers etc.
lengthptr NULL during the real compile phase
@@ -6222,30 +7023,29 @@
*/
static BOOL
-compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr,
+compile_regex(int options, pcre_uchar **codeptr, const pcre_uchar **ptrptr,
int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
- int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd,
- int *lengthptr)
+ int cond_depth, pcre_int32 *firstcharptr, pcre_int32 *reqcharptr,
+ branch_chain *bcptr, compile_data *cd, int *lengthptr)
{
-const uschar *ptr = *ptrptr;
-uschar *code = *codeptr;
-uschar *last_branch = code;
-uschar *start_bracket = code;
-uschar *reverse_count = NULL;
+const pcre_uchar *ptr = *ptrptr;
+pcre_uchar *code = *codeptr;
+pcre_uchar *last_branch = code;
+pcre_uchar *start_bracket = code;
+pcre_uchar *reverse_count = NULL;
open_capitem capitem;
int capnumber = 0;
-int firstbyte, reqbyte;
-int branchfirstbyte, branchreqbyte;
+pcre_int32 firstchar, reqchar;
+pcre_int32 branchfirstchar, branchreqchar;
int length;
int orig_bracount;
int max_bracount;
-int old_external_options = cd->external_options;
branch_chain bc;
bc.outer = bcptr;
bc.current_branch = code;
-firstbyte = reqbyte = REQ_UNSET;
+firstchar = reqchar = REQ_UNSET;
/* Accumulate the length for use in the pre-compile phase. Start with the
length of the BRA and KET and any extra bytes that are required at the
@@ -6263,7 +7063,9 @@
/* If this is a capturing subpattern, add to the chain of open capturing items
so that we can detect them if (*ACCEPT) is encountered. This is also used to
-detect groups that contain recursive back references to themselves. */
+detect groups that contain recursive back references to themselves. Note that
+only OP_CBRA need be tested here; changing this opcode to one of its variants,
+e.g. OP_SCBRAPOS, happens later, after the group has been compiled. */
if (*code == OP_CBRA)
{
@@ -6289,15 +7091,6 @@
if (reset_bracount) cd->bracount = orig_bracount;
- /* Handle a change of ims options at the start of the branch */
-
- if ((options & PCRE_IMS) != oldims)
- {
- *code++ = OP_OPT;
- *code++ = options & PCRE_IMS;
- length += 2;
- }
-
/* Set up dummy OP_REVERSE if lookbehind assertion */
if (lookbehind)
@@ -6311,22 +7104,14 @@
/* Now compile the branch; in the pre-compile phase its length gets added
into the length. */
- if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstbyte,
- &branchreqbyte, &bc, cd, (lengthptr == NULL)? NULL : &length))
+ if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstchar,
+ &branchreqchar, &bc, cond_depth, cd,
+ (lengthptr == NULL)? NULL : &length))
{
*ptrptr = ptr;
return FALSE;
}
- /* If the external options have changed during this branch, it means that we
- are at the top level, and a leading option setting has been encountered. We
- need to re-set the original option values to take account of this so that,
- during the pre-compile phase, we know to allow for a re-set at the start of
- subsequent branches. */
-
- if (old_external_options != cd->external_options)
- oldims = cd->external_options & PCRE_IMS;
-
/* Keep the highest bracket count in case (?| was used and some branch
has fewer than the rest. */
@@ -6336,43 +7121,43 @@
if (lengthptr == NULL)
{
- /* If this is the first branch, the firstbyte and reqbyte values for the
+ /* If this is the first branch, the firstchar and reqchar values for the
branch become the values for the regex. */
if (*last_branch != OP_ALT)
{
- firstbyte = branchfirstbyte;
- reqbyte = branchreqbyte;
+ firstchar = branchfirstchar;
+ reqchar = branchreqchar;
}
- /* If this is not the first branch, the first char and reqbyte have to
+ /* If this is not the first branch, the first char and reqchar have to
match the values from all the previous branches, except that if the
- previous value for reqbyte didn't have REQ_VARY set, it can still match,
+ previous value for reqchar didn't have REQ_VARY set, it can still match,
and we set REQ_VARY for the regex. */
else
{
- /* If we previously had a firstbyte, but it doesn't match the new branch,
- we have to abandon the firstbyte for the regex, but if there was
- previously no reqbyte, it takes on the value of the old firstbyte. */
+ /* If we previously had a firstchar, but it doesn't match the new branch,
+ we have to abandon the firstchar for the regex, but if there was
+ previously no reqchar, it takes on the value of the old firstchar. */
- if (firstbyte >= 0 && firstbyte != branchfirstbyte)
+ if (firstchar >= 0 && firstchar != branchfirstchar)
{
- if (reqbyte < 0) reqbyte = firstbyte;
- firstbyte = REQ_NONE;
+ if (reqchar < 0) reqchar = firstchar;
+ firstchar = REQ_NONE;
}
- /* If we (now or from before) have no firstbyte, a firstbyte from the
- branch becomes a reqbyte if there isn't a branch reqbyte. */
+ /* If we (now or from before) have no firstchar, a firstchar from the
+ branch becomes a reqchar if there isn't a branch reqchar. */
- if (firstbyte < 0 && branchfirstbyte >= 0 && branchreqbyte < 0)
- branchreqbyte = branchfirstbyte;
+ if (firstchar < 0 && branchfirstchar >= 0 && branchreqchar < 0)
+ branchreqchar = branchfirstchar;
- /* Now ensure that the reqbytes match */
+ /* Now ensure that the reqchars match */
- if ((reqbyte & ~REQ_VARY) != (branchreqbyte & ~REQ_VARY))
- reqbyte = REQ_NONE;
- else reqbyte |= branchreqbyte; /* To "or" REQ_VARY */
+ if ((reqchar & ~REQ_VARY) != (branchreqchar & ~REQ_VARY))
+ reqchar = REQ_NONE;
+ else reqchar |= branchreqchar; /* To "or" REQ_VARY */
}
/* If lookbehind, check that this branch matches a fixed-length string, and
@@ -6387,7 +7172,8 @@
{
int fixed_length;
*code = OP_END;
- fixed_length = find_fixedlength(last_branch, options, FALSE, cd);
+ fixed_length = find_fixedlength(last_branch, (options & PCRE_UTF8) != 0,
+ FALSE, cd);
DPRINTF(("fixed length = %d\n", fixed_length));
if (fixed_length == -3)
{
@@ -6395,11 +7181,17 @@
}
else if (fixed_length < 0)
{
- *errorcodeptr = (fixed_length == -2)? ERR36 : ERR25;
+ *errorcodeptr = (fixed_length == -2)? ERR36 :
+ (fixed_length == -4)? ERR70: ERR25;
*ptrptr = ptr;
return FALSE;
}
- else { PUT(reverse_count, 0, fixed_length); }
+ else
+ {
+ if (fixed_length > cd->max_lookbehind)
+ cd->max_lookbehind = fixed_length;
+ PUT(reverse_count, 0, fixed_length);
+ }
}
}
@@ -6408,9 +7200,7 @@
of offsets, with the field in the BRA item now becoming an offset to the
first alternative. If there are no alternatives, it points to the end of the
group. The length in the terminating ket is always the length of the whole
- bracketed item. If any of the ims options were changed inside the group,
- compile a resetting op-code following, except at the very end of the pattern.
- Return leaving the pointer at the terminating char. */
+ bracketed item. Return leaving the pointer at the terminating char. */
if (*ptr != CHAR_VERTICAL_LINE)
{
@@ -6442,7 +7232,7 @@
if (cd->open_caps->flag)
{
memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
- code - start_bracket);
+ IN_UCHARS(code - start_bracket));
*start_bracket = OP_ONCE;
code += 1 + LINK_SIZE;
PUT(start_bracket, 1, (int)(code - start_bracket));
@@ -6454,15 +7244,6 @@
cd->open_caps = cd->open_caps->next;
}
- /* Reset options if needed. */
-
- if ((options & PCRE_IMS) != oldims && *ptr == CHAR_RIGHT_PARENTHESIS)
- {
- *code++ = OP_OPT;
- *code++ = oldims;
- length += 2;
- }
-
/* Retain the highest bracket number, in case resetting was used. */
cd->bracount = max_bracount;
@@ -6471,8 +7252,8 @@
*codeptr = code;
*ptrptr = ptr;
- *firstbyteptr = firstbyte;
- *reqbyteptr = reqbyte;
+ *firstcharptr = firstchar;
+ *reqcharptr = reqchar;
if (lengthptr != NULL)
{
if (OFLOW_MAX - *lengthptr < length)
@@ -6522,8 +7303,8 @@
/* Try to find out if this is an anchored regular expression. Consider each
alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
-it's anchored. However, if this is a multiline pattern, then only OP_SOD
-counts, since OP_CIRC can match in the middle.
+it's anchored. However, if this is a multiline pattern, then only OP_SOD will
+be found, because ^ generates OP_CIRCM in that mode.
We can also consider a regex to be anchored if OP_SOM starts all its branches.
This is the code for \G, which means "match at start of match position, taking
@@ -6544,7 +7325,6 @@
Arguments:
code points to start of expression (the bracket)
- options points to the options setting
bracket_map a bitmap of which brackets we are inside while testing; this
handles up to substring 31; after that we just have to take
the less precise approach
@@ -6554,35 +7334,38 @@
*/
static BOOL
-is_anchored(register const uschar *code, int *options, unsigned int bracket_map,
+is_anchored(register const pcre_uchar *code, unsigned int bracket_map,
unsigned int backref_map)
{
do {
- const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code],
- options, PCRE_MULTILINE, FALSE);
+ const pcre_uchar *scode = first_significant_code(
+ code + PRIV(OP_lengths)[*code], FALSE);
register int op = *scode;
/* Non-capturing brackets */
- if (op == OP_BRA)
+ if (op == OP_BRA || op == OP_BRAPOS ||
+ op == OP_SBRA || op == OP_SBRAPOS)
{
- if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE;
+ if (!is_anchored(scode, bracket_map, backref_map)) return FALSE;
}
/* Capturing brackets */
- else if (op == OP_CBRA)
+ else if (op == OP_CBRA || op == OP_CBRAPOS ||
+ op == OP_SCBRA || op == OP_SCBRAPOS)
{
int n = GET2(scode, 1+LINK_SIZE);
int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
- if (!is_anchored(scode, options, new_map, backref_map)) return FALSE;
+ if (!is_anchored(scode, new_map, backref_map)) return FALSE;
}
/* Other brackets */
- else if (op == OP_ASSERT || op == OP_ONCE || op == OP_COND)
+ else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC ||
+ op == OP_COND)
{
- if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE;
+ if (!is_anchored(scode, bracket_map, backref_map)) return FALSE;
}
/* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
@@ -6597,9 +7380,7 @@
/* Check for explicit anchoring */
- else if (op != OP_SOD && op != OP_SOM &&
- ((*options & PCRE_MULTILINE) != 0 || op != OP_CIRC))
- return FALSE;
+ else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE;
code += GET(code, 1);
}
while (*code == OP_ALT); /* Loop for each alternative */
@@ -6630,12 +7411,12 @@
*/
static BOOL
-is_startline(const uschar *code, unsigned int bracket_map,
+is_startline(const pcre_uchar *code, unsigned int bracket_map,
unsigned int backref_map)
{
do {
- const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code],
- NULL, 0, FALSE);
+ const pcre_uchar *scode = first_significant_code(
+ code + PRIV(OP_lengths)[*code], FALSE);
register int op = *scode;
/* If we are at the start of a conditional assertion group, *both* the
@@ -6646,7 +7427,7 @@
if (op == OP_COND)
{
scode += 1 + LINK_SIZE;
- if (*scode == OP_CALLOUT) scode += _pcre_OP_lengths[OP_CALLOUT];
+ if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT];
switch (*scode)
{
case OP_CREF:
@@ -6662,20 +7443,22 @@
scode += 1 + LINK_SIZE;
break;
}
- scode = first_significant_code(scode, NULL, 0, FALSE);
+ scode = first_significant_code(scode, FALSE);
op = *scode;
}
/* Non-capturing brackets */
- if (op == OP_BRA)
+ if (op == OP_BRA || op == OP_BRAPOS ||
+ op == OP_SBRA || op == OP_SBRAPOS)
{
if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
}
/* Capturing brackets */
- else if (op == OP_CBRA)
+ else if (op == OP_CBRA || op == OP_CBRAPOS ||
+ op == OP_SCBRA || op == OP_SCBRAPOS)
{
int n = GET2(scode, 1+LINK_SIZE);
int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
@@ -6684,7 +7467,7 @@
/* Other brackets */
- else if (op == OP_ASSERT || op == OP_ONCE)
+ else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC)
{
if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
}
@@ -6699,7 +7482,7 @@
/* Check for explicit circumflex */
- else if (op != OP_CIRC) return FALSE;
+ else if (op != OP_CIRC && op != OP_CIRCM) return FALSE;
/* Move on to the next alternative */
@@ -6725,20 +7508,21 @@
Arguments:
code points to start of expression (the bracket)
- options pointer to the options (used to check casing changes)
inassert TRUE if in an assertion
Returns: -1 or the fixed first char
*/
static int
-find_firstassertedchar(const uschar *code, int *options, BOOL inassert)
+find_firstassertedchar(const pcre_uchar *code, BOOL inassert)
{
register int c = -1;
do {
int d;
- const uschar *scode =
- first_significant_code(code + 1+LINK_SIZE, options, PCRE_CASELESS, TRUE);
+ int xl = (*code == OP_CBRA || *code == OP_SCBRA ||
+ *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0;
+ const pcre_uchar *scode = first_significant_code(code + 1+LINK_SIZE + xl,
+ TRUE);
register int op = *scode;
switch(op)
@@ -6747,30 +7531,44 @@
return -1;
case OP_BRA:
+ case OP_BRAPOS:
case OP_CBRA:
+ case OP_SCBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
case OP_ASSERT:
case OP_ONCE:
+ case OP_ONCE_NC:
case OP_COND:
- if ((d = find_firstassertedchar(scode, options, op == OP_ASSERT)) < 0)
+ if ((d = find_firstassertedchar(scode, op == OP_ASSERT)) < 0)
return -1;
if (c < 0) c = d; else if (c != d) return -1;
break;
- case OP_EXACT: /* Fall through */
- scode += 2;
+ case OP_EXACT:
+ scode += IMM2_SIZE;
+ /* Fall through */
case OP_CHAR:
- case OP_CHARNC:
case OP_PLUS:
case OP_MINPLUS:
case OP_POSPLUS:
if (!inassert) return -1;
- if (c < 0)
- {
- c = scode[1];
- if ((*options & PCRE_CASELESS) != 0) c |= REQ_CASELESS;
- }
- else if (c != scode[1]) return -1;
+ if (c < 0) c = scode[1];
+ else if (c != scode[1]) return -1;
+ break;
+
+ case OP_EXACTI:
+ scode += IMM2_SIZE;
+ /* Fall through */
+
+ case OP_CHARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ if (!inassert) return -1;
+ if (c < 0) c = scode[1] | REQ_CASELESS;
+ else if (c != scode[1]) return -1;
break;
}
@@ -6804,28 +7602,45 @@
with errorptr and erroroffset set
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
pcre_compile(const char *pattern, int options, const char **errorptr,
int *erroroffset, const unsigned char *tables)
+#else
+PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION
+pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errorptr,
+ int *erroroffset, const unsigned char *tables)
+#endif
{
+#ifdef COMPILE_PCRE8
return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
+#else
+return pcre16_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
+#endif
}
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
pcre_compile2(const char *pattern, int options, int *errorcodeptr,
const char **errorptr, int *erroroffset, const unsigned char *tables)
+#else
+PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION
+pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr,
+ const char **errorptr, int *erroroffset, const unsigned char *tables)
+#endif
{
-real_pcre *re;
+REAL_PCRE *re;
int length = 1; /* For final END opcode */
-int firstbyte, reqbyte, newline;
+pcre_int32 firstchar, reqchar;
+int newline;
int errorcode = 0;
int skipatstart = 0;
-BOOL utf8;
+BOOL utf;
size_t size;
-uschar *code;
-const uschar *codestart;
-const uschar *ptr;
+pcre_uchar *code;
+const pcre_uchar *codestart;
+const pcre_uchar *ptr;
compile_data compile_block;
compile_data *cd = &compile_block;
@@ -6833,13 +7648,14 @@
computing the amount of memory that is needed. Compiled items are thrown away
as soon as possible, so that a fairly large buffer should be sufficient for
this purpose. The same space is used in the second phase for remembering where
-to fill in forward references to subpatterns. */
+to fill in forward references to subpatterns. That may overflow, in which case
+new memory is obtained from malloc(). */
-uschar cworkspace[COMPILE_WORK_SIZE];
+pcre_uchar cworkspace[COMPILE_WORK_SIZE];
/* Set this early so that early errors get offset 0. */
-ptr = (const uschar *)pattern;
+ptr = (const pcre_uchar *)pattern;
/* We can't pass back an error message if errorptr is NULL; I guess the best we
can do is just return NULL, but we can set a code value if there is a code
@@ -6866,7 +7682,7 @@
/* Set up pointers to the individual character tables */
-if (tables == NULL) tables = _pcre_default_tables;
+if (tables == NULL) tables = PRIV(default_tables);
cd->lcc = tables + lcc_offset;
cd->fcc = tables + fcc_offset;
cd->cbits = tables + cbits_offset;
@@ -6889,27 +7705,33 @@
int newnl = 0;
int newbsr = 0;
- if (strncmp((char *)(ptr+skipatstart+2), STRING_UTF8_RIGHTPAR, 5) == 0)
+#ifdef COMPILE_PCRE8
+ if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 5) == 0)
{ skipatstart += 7; options |= PCRE_UTF8; continue; }
- else if (strncmp((char *)(ptr+skipatstart+2), STRING_UCP_RIGHTPAR, 4) == 0)
+#endif
+#ifdef COMPILE_PCRE16
+ if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 6) == 0)
+ { skipatstart += 8; options |= PCRE_UTF16; continue; }
+#endif
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0)
{ skipatstart += 6; options |= PCRE_UCP; continue; }
- else if (strncmp((char *)(ptr+skipatstart+2), STRING_NO_START_OPT_RIGHTPAR, 13) == 0)
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0)
{ skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; }
- if (strncmp((char *)(ptr+skipatstart+2), STRING_CR_RIGHTPAR, 3) == 0)
+ if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CR_RIGHTPAR, 3) == 0)
{ skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
- else if (strncmp((char *)(ptr+skipatstart+2), STRING_LF_RIGHTPAR, 3) == 0)
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LF_RIGHTPAR, 3) == 0)
{ skipatstart += 5; newnl = PCRE_NEWLINE_LF; }
- else if (strncmp((char *)(ptr+skipatstart+2), STRING_CRLF_RIGHTPAR, 5) == 0)
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CRLF_RIGHTPAR, 5) == 0)
{ skipatstart += 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; }
- else if (strncmp((char *)(ptr+skipatstart+2), STRING_ANY_RIGHTPAR, 4) == 0)
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANY_RIGHTPAR, 4) == 0)
{ skipatstart += 6; newnl = PCRE_NEWLINE_ANY; }
- else if (strncmp((char *)(ptr+skipatstart+2), STRING_ANYCRLF_RIGHTPAR, 8) == 0)
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANYCRLF_RIGHTPAR, 8) == 0)
{ skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; }
- else if (strncmp((char *)(ptr+skipatstart+2), STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0)
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0)
{ skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; }
- else if (strncmp((char *)(ptr+skipatstart+2), STRING_BSR_UNICODE_RIGHTPAR, 12) == 0)
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_UNICODE_RIGHTPAR, 12) == 0)
{ skipatstart += 14; newbsr = PCRE_BSR_UNICODE; }
if (newnl != 0)
@@ -6919,19 +7741,27 @@
else break;
}
-utf8 = (options & PCRE_UTF8) != 0;
-
-/* Can't support UTF8 unless PCRE has been compiled to include the code. */
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+utf = (options & PCRE_UTF8) != 0;
-#ifdef SUPPORT_UTF8
-if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 &&
- (*erroroffset = _pcre_valid_utf8((USPTR)pattern, -1)) >= 0)
+/* Can't support UTF unless PCRE has been compiled to include the code. The
+return of an error code from PRIV(valid_utf)() is a new feature, introduced in
+release 8.13. It is passed back from pcre_[dfa_]exec(), but at the moment is
+not used here. */
+
+#ifdef SUPPORT_UTF
+if (utf && (options & PCRE_NO_UTF8_CHECK) == 0 &&
+ (errorcode = PRIV(valid_utf)((PCRE_PUCHAR)pattern, -1, erroroffset)) != 0)
{
+#ifdef COMPILE_PCRE8
errorcode = ERR44;
+#else
+ errorcode = ERR74;
+#endif
goto PCRE_EARLY_ERROR_RETURN2;
}
#else
-if (utf8)
+if (utf)
{
errorcode = ERR32;
goto PCRE_EARLY_ERROR_RETURN;
@@ -6950,13 +7780,11 @@
/* Check validity of \R options. */
-switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
+if ((options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) ==
+ (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
{
- case 0:
- case PCRE_BSR_ANYCRLF:
- case PCRE_BSR_UNICODE:
- break;
- default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
+ errorcode = ERR56;
+ goto PCRE_EARLY_ERROR_RETURN;
}
/* Handle different types of newline. The three bits give seven cases. The
@@ -7009,7 +7837,10 @@
/* Reflect pattern for debugging output */
DPRINTF(("------------------------------------------------------------------\n"));
-DPRINTF(("%s\n", pattern));
+#ifdef PCRE_DEBUG
+print_puchar(stdout, (PCRE_PUCHAR)pattern);
+#endif
+DPRINTF(("\n"));
/* Pretend to compile the pattern while actually just accumulating the length
of memory required. This behaviour is triggered by passing a non-NULL final
@@ -7022,12 +7853,15 @@
cd->names_found = 0;
cd->name_entry_size = 0;
cd->name_table = NULL;
-cd->start_workspace = cworkspace;
cd->start_code = cworkspace;
cd->hwm = cworkspace;
-cd->start_pattern = (const uschar *)pattern;
-cd->end_pattern = (const uschar *)(pattern + strlen(pattern));
+cd->start_workspace = cworkspace;
+cd->workspace_size = COMPILE_WORK_SIZE;
+cd->start_pattern = (const pcre_uchar *)pattern;
+cd->end_pattern = (const pcre_uchar *)(pattern + STRLEN_UC((const pcre_uchar *)pattern));
cd->req_varyopt = 0;
+cd->assert_depth = 0;
+cd->max_lookbehind = 0;
cd->external_options = options;
cd->external_flags = 0;
cd->open_caps = NULL;
@@ -7041,13 +7875,12 @@
ptr += skipatstart;
code = cworkspace;
*code = OP_BRA;
-(void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS,
- &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd,
- &length);
+(void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE,
+ FALSE, 0, 0, &firstchar, &reqchar, NULL, cd, &length);
if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
- cd->hwm - cworkspace));
+ (int)(cd->hwm - cworkspace)));
if (length > MAX_PATTERN_SIZE)
{
@@ -7060,8 +7893,8 @@
because nowadays we limit the maximum value of cd->names_found and
cd->name_entry_size. */
-size = length + sizeof(real_pcre) + cd->names_found * (cd->name_entry_size + 3);
-re = (real_pcre *)(pcre_malloc)(size);
+size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar);
+re = (REAL_PCRE *)(PUBL(malloc))(size);
if (re == NULL)
{
@@ -7079,14 +7912,13 @@
re->size = (int)size;
re->options = cd->external_options;
re->flags = cd->external_flags;
-re->dummy1 = 0;
-re->first_byte = 0;
-re->req_byte = 0;
-re->name_table_offset = sizeof(real_pcre);
+re->first_char = 0;
+re->req_char = 0;
+re->name_table_offset = sizeof(REAL_PCRE) / sizeof(pcre_uchar);
re->name_entry_size = cd->name_entry_size;
re->name_count = cd->names_found;
re->ref_count = 0;
-re->tables = (tables == _pcre_default_tables)? NULL : tables;
+re->tables = (tables == PRIV(default_tables))? NULL : tables;
re->nullpad = NULL;
/* The starting points of the name/number translation table and of the code are
@@ -7097,12 +7929,14 @@
*/
cd->final_bracount = cd->bracount; /* Save for checking forward references */
+cd->assert_depth = 0;
cd->bracount = 0;
+cd->max_lookbehind = 0;
cd->names_found = 0;
-cd->name_table = (uschar *)re + re->name_table_offset;
+cd->name_table = (pcre_uchar *)re + re->name_table_offset;
codestart = cd->name_table + re->name_entry_size * re->name_count;
cd->start_code = codestart;
-cd->hwm = cworkspace;
+cd->hwm = (pcre_uchar *)(cd->start_workspace);
cd->req_varyopt = 0;
cd->had_accept = FALSE;
cd->check_lookbehind = FALSE;
@@ -7112,16 +7946,17 @@
error, errorcode will be set non-zero, so we don't need to look at the result
of the function here. */
-ptr = (const uschar *)pattern + skipatstart;
-code = (uschar *)codestart;
+ptr = (const pcre_uchar *)pattern + skipatstart;
+code = (pcre_uchar *)codestart;
*code = OP_BRA;
-(void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,
- &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);
+(void)compile_regex(re->options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0,
+ &firstchar, &reqchar, NULL, cd, NULL);
re->top_bracket = cd->bracount;
re->top_backref = cd->top_backref;
-re->flags = cd->external_flags;
+re->max_lookbehind = cd->max_lookbehind;
+re->flags = cd->external_flags | PCRE_MODE;
-if (cd->had_accept) reqbyte = -1; /* Must disable after (*ACCEPT) */
+if (cd->had_accept) reqchar = REQ_NONE; /* Must disable after (*ACCEPT) */
/* If not reached end of pattern on success, there's an excess bracket. */
@@ -7136,20 +7971,34 @@
if (code - codestart > length) errorcode = ERR23;
#endif
-/* Fill in any forward references that are required. */
+/* Fill in any forward references that are required. There may be repeated
+references; optimize for them, as searching a large regex takes time. */
-while (errorcode == 0 && cd->hwm > cworkspace)
+if (cd->hwm > cd->start_workspace)
{
- int offset, recno;
- const uschar *groupptr;
- cd->hwm -= LINK_SIZE;
- offset = GET(cd->hwm, 0);
- recno = GET(codestart, offset);
- groupptr = _pcre_find_bracket(codestart, utf8, recno);
- if (groupptr == NULL) errorcode = ERR53;
- else PUT(((uschar *)codestart), offset, (int)(groupptr - codestart));
+ int prev_recno = -1;
+ const pcre_uchar *groupptr = NULL;
+ while (errorcode == 0 && cd->hwm > cd->start_workspace)
+ {
+ int offset, recno;
+ cd->hwm -= LINK_SIZE;
+ offset = GET(cd->hwm, 0);
+ recno = GET(codestart, offset);
+ if (recno != prev_recno)
+ {
+ groupptr = PRIV(find_bracket)(codestart, utf, recno);
+ prev_recno = recno;
+ }
+ if (groupptr == NULL) errorcode = ERR53;
+ else PUT(((pcre_uchar *)codestart), offset, (int)(groupptr - codestart));
+ }
}
+/* If the workspace had to be expanded, free the new memory. */
+
+if (cd->workspace_size > COMPILE_WORK_SIZE)
+ (PUBL(free))((void *)cd->start_workspace);
+
/* Give an error if there's back reference to a non-existent capturing
subpattern. */
@@ -7165,31 +8014,34 @@
if (cd->check_lookbehind)
{
- uschar *cc = (uschar *)codestart;
+ pcre_uchar *cc = (pcre_uchar *)codestart;
/* Loop, searching for OP_REVERSE items, and process those that do not have
their length set. (Actually, it will also re-process any that have a length
of zero, but that is a pathological case, and it does no harm.) When we find
one, we temporarily terminate the branch it is in while we scan it. */
- for (cc = (uschar *)_pcre_find_bracket(codestart, utf8, -1);
+ for (cc = (pcre_uchar *)PRIV(find_bracket)(codestart, utf, -1);
cc != NULL;
- cc = (uschar *)_pcre_find_bracket(cc, utf8, -1))
+ cc = (pcre_uchar *)PRIV(find_bracket)(cc, utf, -1))
{
if (GET(cc, 1) == 0)
{
int fixed_length;
- uschar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE);
+ pcre_uchar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE);
int end_op = *be;
*be = OP_END;
- fixed_length = find_fixedlength(cc, re->options, TRUE, cd);
+ fixed_length = find_fixedlength(cc, (re->options & PCRE_UTF8) != 0, TRUE,
+ cd);
*be = end_op;
DPRINTF(("fixed length = %d\n", fixed_length));
if (fixed_length < 0)
{
- errorcode = (fixed_length == -2)? ERR36 : ERR25;
+ errorcode = (fixed_length == -2)? ERR36 :
+ (fixed_length == -4)? ERR70 : ERR25;
break;
}
+ if (fixed_length > cd->max_lookbehind) cd->max_lookbehind = fixed_length;
PUT(cc, 1, fixed_length);
}
cc += 1 + LINK_SIZE;
@@ -7200,9 +8052,9 @@
if (errorcode != 0)
{
- (pcre_free)(re);
+ (PUBL(free))(re);
PCRE_EARLY_ERROR_RETURN:
- *erroroffset = (int)(ptr - (const uschar *)pattern);
+ *erroroffset = (int)(ptr - (const pcre_uchar *)pattern);
PCRE_EARLY_ERROR_RETURN2:
*errorptr = find_error_text(errorcode);
if (errorcodeptr != NULL) *errorcodeptr = errorcode;
@@ -7221,18 +8073,42 @@
if ((re->options & PCRE_ANCHORED) == 0)
{
- int temp_options = re->options; /* May get changed during these scans */
- if (is_anchored(codestart, &temp_options, 0, cd->backref_map))
+ if (is_anchored(codestart, 0, cd->backref_map))
re->options |= PCRE_ANCHORED;
else
{
- if (firstbyte < 0)
- firstbyte = find_firstassertedchar(codestart, &temp_options, FALSE);
- if (firstbyte >= 0) /* Remove caseless flag for non-caseable chars */
- {
- int ch = firstbyte & 255;
- re->first_byte = ((firstbyte & REQ_CASELESS) != 0 &&
- cd->fcc[ch] == ch)? ch : firstbyte;
+ if (firstchar < 0)
+ firstchar = find_firstassertedchar(codestart, FALSE);
+ if (firstchar >= 0) /* Remove caseless flag for non-caseable chars */
+ {
+#ifdef COMPILE_PCRE8
+ re->first_char = firstchar & 0xff;
+#else
+#ifdef COMPILE_PCRE16
+ re->first_char = firstchar & 0xffff;
+#endif
+#endif
+ if ((firstchar & REQ_CASELESS) != 0)
+ {
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ /* We ignore non-ASCII first chars in 8 bit mode. */
+ if (utf)
+ {
+ if (re->first_char < 128)
+ {
+ if (cd->fcc[re->first_char] != re->first_char)
+ re->flags |= PCRE_FCH_CASELESS;
+ }
+ else if (UCD_OTHERCASE(re->first_char) != re->first_char)
+ re->flags |= PCRE_FCH_CASELESS;
+ }
+ else
+#endif
+ if (MAX_255(re->first_char)
+ && cd->fcc[re->first_char] != re->first_char)
+ re->flags |= PCRE_FCH_CASELESS;
+ }
+
re->flags |= PCRE_FIRSTSET;
}
else if (is_startline(codestart, 0, cd->backref_map))
@@ -7244,12 +8120,36 @@
variable length item in the regex. Remove the caseless flag for non-caseable
bytes. */
-if (reqbyte >= 0 &&
- ((re->options & PCRE_ANCHORED) == 0 || (reqbyte & REQ_VARY) != 0))
+if (reqchar >= 0 &&
+ ((re->options & PCRE_ANCHORED) == 0 || (reqchar & REQ_VARY) != 0))
{
- int ch = reqbyte & 255;
- re->req_byte = ((reqbyte & REQ_CASELESS) != 0 &&
- cd->fcc[ch] == ch)? (reqbyte & ~REQ_CASELESS) : reqbyte;
+#ifdef COMPILE_PCRE8
+ re->req_char = reqchar & 0xff;
+#else
+#ifdef COMPILE_PCRE16
+ re->req_char = reqchar & 0xffff;
+#endif
+#endif
+ if ((reqchar & REQ_CASELESS) != 0)
+ {
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ /* We ignore non-ASCII first chars in 8 bit mode. */
+ if (utf)
+ {
+ if (re->req_char < 128)
+ {
+ if (cd->fcc[re->req_char] != re->req_char)
+ re->flags |= PCRE_RCH_CASELESS;
+ }
+ else if (UCD_OTHERCASE(re->req_char) != re->req_char)
+ re->flags |= PCRE_RCH_CASELESS;
+ }
+ else
+#endif
+ if (MAX_255(re->req_char) && cd->fcc[re->req_char] != re->req_char)
+ re->flags |= PCRE_RCH_CASELESS;
+ }
+
re->flags |= PCRE_REQCHSET;
}
@@ -7264,38 +8164,46 @@
if ((re->flags & PCRE_FIRSTSET) != 0)
{
- int ch = re->first_byte & 255;
- const char *caseless = ((re->first_byte & REQ_CASELESS) == 0)?
- "" : " (caseless)";
- if (isprint(ch)) printf("First char = %c%s\n", ch, caseless);
+ pcre_uchar ch = re->first_char;
+ const char *caseless =
+ ((re->flags & PCRE_FCH_CASELESS) == 0)? "" : " (caseless)";
+ if (PRINTABLE(ch)) printf("First char = %c%s\n", ch, caseless);
else printf("First char = \\x%02x%s\n", ch, caseless);
}
if ((re->flags & PCRE_REQCHSET) != 0)
{
- int ch = re->req_byte & 255;
- const char *caseless = ((re->req_byte & REQ_CASELESS) == 0)?
- "" : " (caseless)";
- if (isprint(ch)) printf("Req char = %c%s\n", ch, caseless);
+ pcre_uchar ch = re->req_char;
+ const char *caseless =
+ ((re->flags & PCRE_RCH_CASELESS) == 0)? "" : " (caseless)";
+ if (PRINTABLE(ch)) printf("Req char = %c%s\n", ch, caseless);
else printf("Req char = \\x%02x%s\n", ch, caseless);
}
-pcre_printint(re, stdout, TRUE);
+#ifdef COMPILE_PCRE8
+pcre_printint((pcre *)re, stdout, TRUE);
+#else
+pcre16_printint((pcre *)re, stdout, TRUE);
+#endif
/* This check is done here in the debugging case so that the code that
was compiled can be seen. */
if (code - codestart > length)
{
- (pcre_free)(re);
+ (PUBL(free))(re);
*errorptr = find_error_text(ERR23);
- *erroroffset = ptr - (uschar *)pattern;
+ *erroroffset = ptr - (pcre_uchar *)pattern;
if (errorcodeptr != NULL) *errorcodeptr = ERR23;
return NULL;
}
#endif /* PCRE_DEBUG */
+#ifdef COMPILE_PCRE8
return (pcre *)re;
+#else
+return (pcre16 *)re;
+#endif
}
/* End of pcre_compile.c */
diff -Nru pcre3-8.12/pcre_config.c pcre3-8.31/pcre_config.c
--- pcre3-8.12/pcre_config.c 2009-02-28 15:49:03.000000000 +0000
+++ pcre3-8.31/pcre_config.c 2012-01-17 14:10:47.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2009 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,9 @@
#include "config.h"
#endif
+/* Keep the original link size. */
+static int real_link_size = LINK_SIZE;
+
#include "pcre_internal.h"
@@ -62,18 +65,41 @@
Returns: 0 if data returned, negative on error
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_config(int what, void *where)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_config(int what, void *where)
+#endif
{
switch (what)
{
case PCRE_CONFIG_UTF8:
-#ifdef SUPPORT_UTF8
+#if defined COMPILE_PCRE16
+ *((int *)where) = 0;
+ return PCRE_ERROR_BADOPTION;
+#else
+#if defined SUPPORT_UTF
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+#endif
+
+ case PCRE_CONFIG_UTF16:
+#if defined COMPILE_PCRE8
+ *((int *)where) = 0;
+ return PCRE_ERROR_BADOPTION;
+#else
+#if defined SUPPORT_UTF
*((int *)where) = 1;
#else
*((int *)where) = 0;
#endif
break;
+#endif
case PCRE_CONFIG_UNICODE_PROPERTIES:
#ifdef SUPPORT_UCP
@@ -83,6 +109,22 @@
#endif
break;
+ case PCRE_CONFIG_JIT:
+#ifdef SUPPORT_JIT
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+
+ case PCRE_CONFIG_JITTARGET:
+#ifdef SUPPORT_JIT
+ *((const char **)where) = PRIV(jit_get_target)();
+#else
+ *((const char **)where) = NULL;
+#endif
+ break;
+
case PCRE_CONFIG_NEWLINE:
*((int *)where) = NEWLINE;
break;
@@ -96,7 +138,7 @@
break;
case PCRE_CONFIG_LINK_SIZE:
- *((int *)where) = LINK_SIZE;
+ *((int *)where) = real_link_size;
break;
case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD:
diff -Nru pcre3-8.12/pcre_dfa_exec.c pcre3-8.31/pcre_dfa_exec.c
--- pcre3-8.12/pcre_dfa_exec.c 2010-11-24 17:38:32.000000000 +0000
+++ pcre3-8.31/pcre_dfa_exec.c 2012-06-20 15:08:50.000000000 +0000
@@ -7,7 +7,7 @@
below for why this module is different).
Written by Philip Hazel
- Copyright (c) 1997-2010 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -38,10 +38,9 @@
-----------------------------------------------------------------------------
*/
-
/* This module contains the external function pcre_dfa_exec(), which is an
alternative matching function that uses a sort of DFA algorithm (not a true
-FSM). This is NOT Perl- compatible, but it has advantages in certain
+FSM). This is NOT Perl-compatible, but it has advantages in certain
applications. */
@@ -113,7 +112,7 @@
the character is to be found. ***NOTE*** If the start of this table is
modified, the three tables that follow must also be modified. */
-static const uschar coptable[] = {
+static const pcre_uint8 coptable[] = {
0, /* End */
0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */
0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */
@@ -121,22 +120,34 @@
0, 0, /* \P, \p */
0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */
0, /* \X */
- 0, 0, 0, 0, 0, /* \Z, \z, Opt, ^, $ */
+ 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */
1, /* Char */
- 1, /* Charnc */
+ 1, /* Chari */
1, /* not */
+ 1, /* noti */
/* Positive single-char repeats */
1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
- 3, 3, 3, /* upto, minupto, exact */
- 1, 1, 1, 3, /* *+, ++, ?+, upto+ */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto, minupto */
+ 1+IMM2_SIZE, /* exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto I, minupto I */
+ 1+IMM2_SIZE, /* exact I */
+ 1, 1, 1, 1+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */
/* Negative single-char repeats - only for chars < 256 */
1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
- 3, 3, 3, /* NOT upto, minupto, exact */
- 1, 1, 1, 3, /* NOT *+, ++, ?+, updo+ */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto, minupto */
+ 1+IMM2_SIZE, /* NOT exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* NOT *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto I, minupto I */
+ 1+IMM2_SIZE, /* NOT exact I */
+ 1, 1, 1, 1+IMM2_SIZE, /* NOT *+I, ++I, ?+I, upto+I */
/* Positive type repeats */
1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
- 3, 3, 3, /* Type upto, minupto, exact */
- 1, 1, 1, 3, /* Type *+, ++, ?+, upto+ */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* Type upto, minupto */
+ 1+IMM2_SIZE, /* Type exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* Type *+, ++, ?+, upto+ */
/* Character class & ref repeats */
0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */
0, 0, /* CRRANGE, CRMINRANGE */
@@ -144,26 +155,30 @@
0, /* NCLASS */
0, /* XCLASS - variable length */
0, /* REF */
+ 0, /* REFI */
0, /* RECURSE */
0, /* CALLOUT */
0, /* Alt */
0, /* Ket */
0, /* KetRmax */
0, /* KetRmin */
+ 0, /* KetRpos */
+ 0, /* Reverse */
0, /* Assert */
0, /* Assert not */
0, /* Assert behind */
0, /* Assert behind not */
- 0, /* Reverse */
- 0, 0, 0, 0, /* ONCE, BRA, CBRA, COND */
- 0, 0, 0, /* SBRA, SCBRA, SCOND */
+ 0, 0, /* ONCE, ONCE_NC */
+ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
+ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
0, 0, /* CREF, NCREF */
0, 0, /* RREF, NRREF */
0, /* DEF */
- 0, 0, /* BRAZERO, BRAMINZERO */
- 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG, */
- 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG, */
- 0, 0, 0, 0, 0 /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO */
+ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
+ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
+ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
+ 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
+ 0, 0 /* CLOSE, SKIPZERO */
};
/* This table identifies those opcodes that inspect a character. It is used to
@@ -171,7 +186,7 @@
the subject is reached. ***NOTE*** If the start of this table is modified, the
two tables that follow must also be modified. */
-static const uschar poptable[] = {
+static const pcre_uint8 poptable[] = {
0, /* End */
0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */
1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */
@@ -179,18 +194,25 @@
1, 1, /* \P, \p */
1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */
1, /* \X */
- 0, 0, 0, 0, 0, /* \Z, \z, Opt, ^, $ */
+ 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */
1, /* Char */
- 1, /* Charnc */
+ 1, /* Chari */
1, /* not */
+ 1, /* noti */
/* Positive single-char repeats */
1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
1, 1, 1, /* upto, minupto, exact */
1, 1, 1, 1, /* *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
+ 1, 1, 1, /* upto I, minupto I, exact I */
+ 1, 1, 1, 1, /* *+I, ++I, ?+I, upto+I */
/* Negative single-char repeats - only for chars < 256 */
1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
1, 1, 1, /* NOT upto, minupto, exact */
1, 1, 1, 1, /* NOT *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
+ 1, 1, 1, /* NOT upto I, minupto I, exact I */
+ 1, 1, 1, 1, /* NOT *+I, ++I, ?+I, upto+I */
/* Positive type repeats */
1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
1, 1, 1, /* Type upto, minupto, exact */
@@ -202,32 +224,36 @@
1, /* NCLASS */
1, /* XCLASS - variable length */
0, /* REF */
+ 0, /* REFI */
0, /* RECURSE */
0, /* CALLOUT */
0, /* Alt */
0, /* Ket */
0, /* KetRmax */
0, /* KetRmin */
+ 0, /* KetRpos */
+ 0, /* Reverse */
0, /* Assert */
0, /* Assert not */
0, /* Assert behind */
0, /* Assert behind not */
- 0, /* Reverse */
- 0, 0, 0, 0, /* ONCE, BRA, CBRA, COND */
- 0, 0, 0, /* SBRA, SCBRA, SCOND */
+ 0, 0, /* ONCE, ONCE_NC */
+ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
+ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
0, 0, /* CREF, NCREF */
0, 0, /* RREF, NRREF */
0, /* DEF */
- 0, 0, /* BRAZERO, BRAMINZERO */
- 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG, */
- 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG, */
- 0, 0, 0, 0, 0 /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO */
+ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
+ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
+ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
+ 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
+ 0, 0 /* CLOSE, SKIPZERO */
};
/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W,
and \w */
-static const uschar toptable1[] = {
+static const pcre_uint8 toptable1[] = {
0, 0, 0, 0, 0, 0,
ctype_digit, ctype_digit,
ctype_space, ctype_space,
@@ -235,7 +261,7 @@
0, 0 /* OP_ANY, OP_ALLANY */
};
-static const uschar toptable2[] = {
+static const pcre_uint8 toptable2[] = {
0, 0, 0, 0, 0, 0,
ctype_digit, 0,
ctype_space, 0,
@@ -252,11 +278,10 @@
typedef struct stateblock {
int offset; /* Offset to opcode */
int count; /* Count for repeats */
- int ims; /* ims flag bits */
int data; /* Some use extra data */
} stateblock;
-#define INTS_PER_STATEBLOCK (sizeof(stateblock)/sizeof(int))
+#define INTS_PER_STATEBLOCK (int)(sizeof(stateblock)/sizeof(int))
#ifdef PCRE_DEBUG
@@ -275,7 +300,7 @@
*/
static void
-pchars(unsigned char *p, int length, FILE *f)
+pchars(const pcre_uchar *p, int length, FILE *f)
{
int c;
while (length-- > 0)
@@ -308,9 +333,7 @@
offsetcount size of same
workspace vector of workspace
wscount size of same
- ims the current ims flags
rlevel function call recursion level
- recursing regex recursive call level
Returns: > 0 => number of match offset pairs placed in offsets
= 0 => offsets overflowed; longest matches are present
@@ -325,7 +348,6 @@
{ \
next_active_state->offset = (x); \
next_active_state->count = (y); \
- next_active_state->ims = ims; \
next_active_state++; \
DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
} \
@@ -336,7 +358,6 @@
{ \
next_active_state->offset = (x); \
next_active_state->count = (y); \
- next_active_state->ims = ims; \
next_active_state->data = (z); \
next_active_state++; \
DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
@@ -348,7 +369,6 @@
{ \
next_new_state->offset = (x); \
next_new_state->count = (y); \
- next_new_state->ims = ims; \
next_new_state++; \
DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
} \
@@ -359,10 +379,10 @@
{ \
next_new_state->offset = (x); \
next_new_state->count = (y); \
- next_new_state->ims = ims; \
next_new_state->data = (z); \
next_new_state++; \
- DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
+ DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d) line %d\n", rlevel*2-2, SP, \
+ (x), (y), (z), __LINE__)); \
} \
else return PCRE_ERROR_DFA_WSSIZE
@@ -371,39 +391,41 @@
static int
internal_dfa_exec(
dfa_match_data *md,
- const uschar *this_start_code,
- const uschar *current_subject,
+ const pcre_uchar *this_start_code,
+ const pcre_uchar *current_subject,
int start_offset,
int *offsets,
int offsetcount,
int *workspace,
int wscount,
- int ims,
- int rlevel,
- int recursing)
+ int rlevel)
{
stateblock *active_states, *new_states, *temp_states;
stateblock *next_active_state, *next_new_state;
-const uschar *ctypes, *lcc, *fcc;
-const uschar *ptr;
-const uschar *end_code, *first_op;
+const pcre_uint8 *ctypes, *lcc, *fcc;
+const pcre_uchar *ptr;
+const pcre_uchar *end_code, *first_op;
+
+dfa_recursion_info new_recursive;
int active_count, new_count, match_count;
/* Some fields in the md block are frequently referenced, so we load them into
independent variables in the hope that this will perform better. */
-const uschar *start_subject = md->start_subject;
-const uschar *end_subject = md->end_subject;
-const uschar *start_code = md->start_code;
+const pcre_uchar *start_subject = md->start_subject;
+const pcre_uchar *end_subject = md->end_subject;
+const pcre_uchar *start_code = md->start_code;
-#ifdef SUPPORT_UTF8
-BOOL utf8 = (md->poptions & PCRE_UTF8) != 0;
+#ifdef SUPPORT_UTF
+BOOL utf = (md->poptions & PCRE_UTF8) != 0;
#else
-BOOL utf8 = FALSE;
+BOOL utf = FALSE;
#endif
+BOOL reset_could_continue = FALSE;
+
rlevel++;
offsetcount &= (-2);
@@ -412,8 +434,8 @@
(2 * INTS_PER_STATEBLOCK);
DPRINTF(("\n%.*s---------------------\n"
- "%.*sCall to internal_dfa_exec f=%d r=%d\n",
- rlevel*2-2, SP, rlevel*2-2, SP, rlevel, recursing));
+ "%.*sCall to internal_dfa_exec f=%d\n",
+ rlevel*2-2, SP, rlevel*2-2, SP, rlevel));
ctypes = md->tables + ctypes_offset;
lcc = md->tables + lcc_offset;
@@ -426,7 +448,9 @@
new_count = 0;
first_op = this_start_code + 1 + LINK_SIZE +
- ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0);
+ ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
+ *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
+ ? IMM2_SIZE:0);
/* The first thing in any (sub) pattern is a bracket of some sort. Push all
the alternative states onto the list, and find out where the end is. This
@@ -454,18 +478,16 @@
/* If we can't go back the amount required for the longest lookbehind
pattern, go back as far as we can; some alternatives may still be viable. */
-#ifdef SUPPORT_UTF8
+#ifdef SUPPORT_UTF
/* In character mode we have to step back character by character */
- if (utf8)
+ if (utf)
{
for (gone_back = 0; gone_back < max_back; gone_back++)
{
if (current_subject <= start_subject) break;
current_subject--;
- while (current_subject > start_subject &&
- (*current_subject & 0xc0) == 0x80)
- current_subject--;
+ ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--);
}
}
else
@@ -525,7 +547,9 @@
else
{
int length = 1 + LINK_SIZE +
- ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0);
+ ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
+ *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
+ ? IMM2_SIZE:0);
do
{
ADD_NEW((int)(end_code - start_code + length), 0);
@@ -538,7 +562,7 @@
workspace[0] = 0; /* Bit indicating which vector is current */
-DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, end_code - start_code));
+DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, (int)(end_code - start_code)));
/* Loop for scanning the subject */
@@ -549,7 +573,9 @@
int clen, dlen;
unsigned int c, d;
int forced_fail = 0;
- BOOL could_continue = FALSE;
+ BOOL partial_newline = FALSE;
+ BOOL could_continue = reset_could_continue;
+ reset_could_continue = FALSE;
/* Make the new state list into the active state list and empty the
new state list. */
@@ -565,7 +591,7 @@
#ifdef PCRE_DEBUG
printf("%.*sNext character: rest of subject = \"", rlevel*2-2, SP);
- pchars((uschar *)ptr, strlen((char *)ptr), stdout);
+ pchars(ptr, STRLEN_UC(ptr), stdout);
printf("\"\n");
printf("%.*sActive states: ", rlevel*2-2, SP);
@@ -585,10 +611,10 @@
if (ptr < end_subject)
{
- clen = 1; /* Number of bytes in the character */
-#ifdef SUPPORT_UTF8
- if (utf8) { GETCHARLEN(c, ptr, clen); } else
-#endif /* SUPPORT_UTF8 */
+ clen = 1; /* Number of data items in the character */
+#ifdef SUPPORT_UTF
+ if (utf) { GETCHARLEN(c, ptr, clen); } else
+#endif /* SUPPORT_UTF */
c = *ptr;
}
else
@@ -605,7 +631,8 @@
for (i = 0; i < active_count; i++)
{
stateblock *current_state = active_states + i;
- const uschar *code;
+ BOOL caseless = FALSE;
+ const pcre_uchar *code;
int state_offset = current_state->offset;
int count, codevalue, rrc;
@@ -616,13 +643,10 @@
else printf("0x%02x\n", c);
#endif
- /* This variable is referred to implicity in the ADD_xxx macros. */
-
- ims = current_state->ims;
-
/* A negative offset is a special case meaning "hold off going to this
(negated) state until the number of characters in the data field have
- been skipped". */
+ been skipped". If the could_continue flag was passed over from a previous
+ state, arrange for it to passed on. */
if (state_offset < 0)
{
@@ -631,6 +655,7 @@
DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP));
ADD_NEW_DATA(state_offset, current_state->count,
current_state->data - 1);
+ if (could_continue) reset_could_continue = TRUE;
continue;
}
else
@@ -670,17 +695,17 @@
permitted.
We also use this mechanism for opcodes such as OP_TYPEPLUS that take an
- argument that is not a data character - but is always one byte long. We
- have to take special action to deal with \P, \p, \H, \h, \V, \v and \X in
- this case. To keep the other cases fast, convert these ones to new opcodes.
- */
+ argument that is not a data character - but is always one byte long because
+ the values are small. We have to take special action to deal with \P, \p,
+ \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert
+ these ones to new opcodes. */
if (coptable[codevalue] > 0)
{
dlen = 1;
-#ifdef SUPPORT_UTF8
- if (utf8) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else
-#endif /* SUPPORT_UTF8 */
+#ifdef SUPPORT_UTF
+ if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else
+#endif /* SUPPORT_UTF */
d = code[coptable[codevalue]];
if (codevalue >= OP_TYPESTAR)
{
@@ -725,7 +750,12 @@
/* ========================================================================== */
/* Reached a closing bracket. If not at the end of the pattern, carry
- on with the next opcode. Otherwise, unless we have an empty string and
+ on with the next opcode. For repeating opcodes, also add the repeat
+ state. Note that KETRPOS will always be encountered at the end of the
+ subpattern, because the possessive subpattern repeats are always handled
+ using recursive calls. Thus, it never adds any new states.
+
+ At the end of the (sub)pattern, unless we have an empty string and
PCRE_NOTEMPTY is set, or PCRE_NOTEMPTY_ATSTART is set and we are at the
start of the subject, save the match data, shifting up all previous
matches so we always have the longest first. */
@@ -733,6 +763,7 @@
case OP_KET:
case OP_KETRMIN:
case OP_KETRMAX:
+ case OP_KETRPOS:
if (code != end_code)
{
ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);
@@ -749,7 +780,7 @@
current_subject > start_subject + md->start_offset)))
{
if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0;
- else if (match_count > 0 && ++match_count * 2 >= offsetcount)
+ else if (match_count > 0 && ++match_count * 2 > offsetcount)
match_count = 0;
count = ((match_count == 0)? offsetcount : match_count * 2) - 2;
if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int));
@@ -758,7 +789,7 @@
offsets[0] = (int)(current_subject - start_subject);
offsets[1] = (int)(ptr - start_subject);
DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,
- offsets[1] - offsets[0], current_subject));
+ offsets[1] - offsets[0], (char *)current_subject));
}
if ((md->moptions & PCRE_DFA_SHORTEST) != 0)
{
@@ -795,7 +826,7 @@
/*-----------------------------------------------------------------*/
case OP_CBRA:
case OP_SCBRA:
- ADD_ACTIVE((int)(code - start_code + 3 + LINK_SIZE), 0);
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE), 0);
code += GET(code, 1);
while (*code == OP_ALT)
{
@@ -822,10 +853,14 @@
/*-----------------------------------------------------------------*/
case OP_CIRC:
+ if (ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0)
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CIRCM:
if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) ||
- ((ims & PCRE_MULTILINE) != 0 &&
- ptr != end_subject &&
- WAS_NEWLINE(ptr)))
+ (ptr != end_subject && WAS_NEWLINE(ptr)))
{ ADD_ACTIVE(state_offset + 1, 0); }
break;
@@ -840,12 +875,6 @@
break;
/*-----------------------------------------------------------------*/
- case OP_OPT:
- ims = code[1];
- ADD_ACTIVE(state_offset + 2, 0);
- break;
-
- /*-----------------------------------------------------------------*/
case OP_SOD:
if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); }
break;
@@ -865,7 +894,20 @@
/*-----------------------------------------------------------------*/
case OP_ANY:
if (clen > 0 && !IS_NEWLINE(ptr))
- { ADD_NEW(state_offset + 1, 0); }
+ {
+ if (ptr + 1 >= md->end_subject &&
+ (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else
+ {
+ ADD_NEW(state_offset + 1, 0);
+ }
+ }
break;
/*-----------------------------------------------------------------*/
@@ -890,11 +932,49 @@
could_continue = TRUE;
else if (clen == 0 ||
((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&
- ((ims & PCRE_MULTILINE) != 0 || ptr == end_subject - md->nllen)
+ (ptr == end_subject - md->nllen)
))
{ ADD_ACTIVE(state_offset + 1, 0); }
+ else if (ptr + 1 >= md->end_subject &&
+ (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
+ {
+ reset_could_continue = TRUE;
+ ADD_NEW_DATA(-(state_offset + 1), 0, 1);
+ }
+ else could_continue = partial_newline = TRUE;
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_DOLLM:
+ if ((md->moptions & PCRE_NOTEOL) == 0)
+ {
+ if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else if (clen == 0 ||
+ ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ else if (ptr + 1 >= md->end_subject &&
+ (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
+ {
+ reset_could_continue = TRUE;
+ ADD_NEW_DATA(-(state_offset + 1), 0, 1);
+ }
+ else could_continue = partial_newline = TRUE;
+ }
}
- else if ((ims & PCRE_MULTILINE) != 0 && IS_NEWLINE(ptr))
+ else if (IS_NEWLINE(ptr))
{ ADD_ACTIVE(state_offset + 1, 0); }
break;
@@ -925,10 +1005,10 @@
if (ptr > start_subject)
{
- const uschar *temp = ptr - 1;
+ const pcre_uchar *temp = ptr - 1;
if (temp < md->start_used_ptr) md->start_used_ptr = temp;
-#ifdef SUPPORT_UTF8
- if (utf8) BACKCHAR(temp);
+#ifdef SUPPORT_UTF
+ if (utf) { BACKCHAR(temp); }
#endif
GETCHARTEST(d, temp);
#ifdef SUPPORT_UCP
@@ -993,7 +1073,7 @@
break;
case PT_GC:
- OK = _pcre_ucp_gentype[prop->chartype] == code[2];
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[2];
break;
case PT_PC:
@@ -1007,24 +1087,24 @@
/* These are specials for combination cases. */
case PT_ALNUM:
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N;
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
break;
case PT_SPACE: /* Perl space */
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
break;
case PT_PXSPACE: /* POSIX space */
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
c == CHAR_FF || c == CHAR_CR;
break;
case PT_WORD:
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
c == CHAR_UNDERSCORE;
break;
@@ -1055,7 +1135,15 @@
if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
if (clen > 0)
{
- if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ if (d == OP_ANY && ptr + 1 >= md->end_subject &&
+ (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
(c < 256 &&
(d != OP_ANY || !IS_NEWLINE(ptr)) &&
((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
@@ -1078,7 +1166,15 @@
ADD_ACTIVE(state_offset + 2, 0);
if (clen > 0)
{
- if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ if (d == OP_ANY && ptr + 1 >= md->end_subject &&
+ (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
(c < 256 &&
(d != OP_ANY || !IS_NEWLINE(ptr)) &&
((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
@@ -1100,7 +1196,15 @@
ADD_ACTIVE(state_offset + 2, 0);
if (clen > 0)
{
- if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ if (d == OP_ANY && ptr + 1 >= md->end_subject &&
+ (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
(c < 256 &&
(d != OP_ANY || !IS_NEWLINE(ptr)) &&
((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
@@ -1120,13 +1224,21 @@
count = current_state->count; /* Number already matched */
if (clen > 0)
{
- if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ if (d == OP_ANY && ptr + 1 >= md->end_subject &&
+ (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
(c < 256 &&
(d != OP_ANY || !IS_NEWLINE(ptr)) &&
((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
{
if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + 4, 0); }
+ { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }
else
{ ADD_NEW(state_offset, count); }
}
@@ -1137,11 +1249,19 @@
case OP_TYPEUPTO:
case OP_TYPEMINUPTO:
case OP_TYPEPOSUPTO:
- ADD_ACTIVE(state_offset + 4, 0);
+ ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0);
count = current_state->count; /* Number already matched */
if (clen > 0)
{
- if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ if (d == OP_ANY && ptr + 1 >= md->end_subject &&
+ (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ could_continue = partial_newline = TRUE;
+ }
+ else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
(c < 256 &&
(d != OP_ANY || !IS_NEWLINE(ptr)) &&
((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
@@ -1152,7 +1272,7 @@
next_active_state--;
}
if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + 4, 0); }
+ { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }
else
{ ADD_NEW(state_offset, count); }
}
@@ -1187,7 +1307,7 @@
break;
case PT_GC:
- OK = _pcre_ucp_gentype[prop->chartype] == code[3];
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
break;
case PT_PC:
@@ -1201,24 +1321,24 @@
/* These are specials for combination cases. */
case PT_ALNUM:
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N;
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
break;
case PT_SPACE: /* Perl space */
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
break;
case PT_PXSPACE: /* POSIX space */
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
c == CHAR_FF || c == CHAR_CR;
break;
case PT_WORD:
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
c == CHAR_UNDERSCORE;
break;
@@ -1250,7 +1370,7 @@
if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
{
- const uschar *nptr = ptr + clen;
+ const pcre_uchar *nptr = ptr + clen;
int ncount = 0;
if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
{
@@ -1434,7 +1554,7 @@
break;
case PT_GC:
- OK = _pcre_ucp_gentype[prop->chartype] == code[3];
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
break;
case PT_PC:
@@ -1448,24 +1568,24 @@
/* These are specials for combination cases. */
case PT_ALNUM:
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N;
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
break;
case PT_SPACE: /* Perl space */
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
break;
case PT_PXSPACE: /* POSIX space */
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
c == CHAR_FF || c == CHAR_CR;
break;
case PT_WORD:
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
c == CHAR_UNDERSCORE;
break;
@@ -1506,7 +1626,7 @@
ADD_ACTIVE(state_offset + 2, 0);
if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
{
- const uschar *nptr = ptr + clen;
+ const pcre_uchar *nptr = ptr + clen;
int ncount = 0;
if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)
@@ -1688,13 +1808,13 @@
case OP_PROP_EXTRA + OP_TYPEMINUPTO:
case OP_PROP_EXTRA + OP_TYPEPOSUPTO:
if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 6, 0); }
+ { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); }
count = current_state->count; /* Number already matched */
if (clen > 0)
{
BOOL OK;
const ucd_record * prop = GET_UCD(c);
- switch(code[4])
+ switch(code[1 + IMM2_SIZE + 1])
{
case PT_ANY:
OK = TRUE;
@@ -1706,38 +1826,38 @@
break;
case PT_GC:
- OK = _pcre_ucp_gentype[prop->chartype] == code[5];
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2];
break;
case PT_PC:
- OK = prop->chartype == code[5];
+ OK = prop->chartype == code[1 + IMM2_SIZE + 2];
break;
case PT_SC:
- OK = prop->script == code[5];
+ OK = prop->script == code[1 + IMM2_SIZE + 2];
break;
/* These are specials for combination cases. */
case PT_ALNUM:
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N;
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
break;
case PT_SPACE: /* Perl space */
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
break;
case PT_PXSPACE: /* POSIX space */
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
c == CHAR_FF || c == CHAR_CR;
break;
case PT_WORD:
- OK = _pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N ||
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
c == CHAR_UNDERSCORE;
break;
@@ -1756,7 +1876,7 @@
next_active_state--;
}
if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + 6, 0); }
+ { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }
else
{ ADD_NEW(state_offset, count); }
}
@@ -1769,11 +1889,11 @@
case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO:
case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO:
if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 4, 0); }
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
count = current_state->count; /* Number already matched */
if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
{
- const uschar *nptr = ptr + clen;
+ const pcre_uchar *nptr = ptr + clen;
int ncount = 0;
if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
{
@@ -1789,8 +1909,10 @@
ncount++;
nptr += ndlen;
}
+ if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
+ reset_could_continue = TRUE;
if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 4), 0, ncount); }
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
else
{ ADD_NEW_DATA(-state_offset, count, ncount); }
}
@@ -1803,7 +1925,7 @@
case OP_ANYNL_EXTRA + OP_TYPEMINUPTO:
case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO:
if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 4, 0); }
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
count = current_state->count; /* Number already matched */
if (clen > 0)
{
@@ -1830,7 +1952,7 @@
next_active_state--;
}
if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 4), 0, ncount); }
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
else
{ ADD_NEW_DATA(-state_offset, count, ncount); }
break;
@@ -1847,7 +1969,7 @@
case OP_VSPACE_EXTRA + OP_TYPEMINUPTO:
case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO:
if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 4, 0); }
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
count = current_state->count; /* Number already matched */
if (clen > 0)
{
@@ -1876,7 +1998,7 @@
next_active_state--;
}
if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 4), 0, 0); }
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
else
{ ADD_NEW_DATA(-state_offset, count, 0); }
}
@@ -1889,7 +2011,7 @@
case OP_HSPACE_EXTRA + OP_TYPEMINUPTO:
case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO:
if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT)
- { ADD_ACTIVE(state_offset + 4, 0); }
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
count = current_state->count; /* Number already matched */
if (clen > 0)
{
@@ -1931,7 +2053,7 @@
next_active_state--;
}
if (++count >= GET2(code, 1))
- { ADD_NEW_DATA(-(state_offset + 4), 0, 0); }
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
else
{ ADD_NEW_DATA(-state_offset, count, 0); }
}
@@ -1950,35 +2072,35 @@
break;
/*-----------------------------------------------------------------*/
- case OP_CHARNC:
+ case OP_CHARI:
if (clen == 0) break;
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else
{
unsigned int othercase;
- if (c < 128) othercase = fcc[c]; else
-
- /* If we have Unicode property support, we can use it to test the
- other case of the character. */
-
+ if (c < 128)
+ othercase = fcc[c];
+ else
+ /* If we have Unicode property support, we can use it to test the
+ other case of the character. */
#ifdef SUPPORT_UCP
- othercase = UCD_OTHERCASE(c);
+ othercase = UCD_OTHERCASE(c);
#else
- othercase = NOTACHAR;
+ othercase = NOTACHAR;
#endif
if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); }
}
}
else
-#endif /* SUPPORT_UTF8 */
-
- /* Non-UTF-8 mode */
+#endif /* SUPPORT_UTF */
+ /* Not UTF mode */
{
- if (lcc[c] == lcc[d]) { ADD_NEW(state_offset + 2, 0); }
+ if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d))
+ { ADD_NEW(state_offset + 2, 0); }
}
break;
@@ -1992,7 +2114,7 @@
case OP_EXTUNI:
if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
{
- const uschar *nptr = ptr + clen;
+ const pcre_uchar *nptr = ptr + clen;
int ncount = 0;
while (nptr < end_subject)
{
@@ -2002,6 +2124,8 @@
ncount++;
nptr += nclen;
}
+ if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
+ reset_could_continue = TRUE;
ADD_NEW_DATA(-(state_offset + 1), 0, ncount);
}
break;
@@ -2027,7 +2151,13 @@
break;
case 0x000d:
- if (ptr + 1 < end_subject && ptr[1] == 0x0a)
+ if (ptr + 1 >= end_subject)
+ {
+ ADD_NEW(state_offset + 1, 0);
+ if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
+ reset_could_continue = TRUE;
+ }
+ else if (ptr[1] == 0x0a)
{
ADD_NEW_DATA(-(state_offset + 1), 0, 1);
}
@@ -2136,19 +2266,45 @@
break;
/*-----------------------------------------------------------------*/
- /* Match a negated single character. This is only used for one-byte
- characters, that is, we know that d < 256. The character we are
- checking (c) can be multibyte. */
+ /* Match a negated single character casefully. */
case OP_NOT:
+ if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ /* Match a negated single character caselessly. */
+
+ case OP_NOTI:
if (clen > 0)
{
- unsigned int otherd = ((ims & PCRE_CASELESS) != 0)? fcc[d] : d;
- if (c != d && c != otherd) { ADD_NEW(state_offset + dlen + 1, 0); }
+ unsigned int otherd;
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
+ {
+#ifdef SUPPORT_UCP
+ otherd = UCD_OTHERCASE(d);
+#endif /* SUPPORT_UCP */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
+ if (c != d && c != otherd)
+ { ADD_NEW(state_offset + dlen + 1, 0); }
}
break;
/*-----------------------------------------------------------------*/
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTPOSPLUSI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+
+ /* Fall through */
case OP_PLUS:
case OP_MINPLUS:
case OP_POSPLUS:
@@ -2160,18 +2316,18 @@
if (clen > 0)
{
unsigned int otherd = NOTACHAR;
- if ((ims & PCRE_CASELESS) != 0)
+ if (caseless)
{
-#ifdef SUPPORT_UTF8
- if (utf8 && d >= 128)
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
{
#ifdef SUPPORT_UCP
otherd = UCD_OTHERCASE(d);
#endif /* SUPPORT_UCP */
}
else
-#endif /* SUPPORT_UTF8 */
- otherd = fcc[d];
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
}
if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
{
@@ -2188,6 +2344,15 @@
break;
/*-----------------------------------------------------------------*/
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTPOSQUERYI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
case OP_QUERY:
case OP_MINQUERY:
case OP_POSQUERY:
@@ -2198,18 +2363,18 @@
if (clen > 0)
{
unsigned int otherd = NOTACHAR;
- if ((ims & PCRE_CASELESS) != 0)
+ if (caseless)
{
-#ifdef SUPPORT_UTF8
- if (utf8 && d >= 128)
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
{
#ifdef SUPPORT_UCP
otherd = UCD_OTHERCASE(d);
#endif /* SUPPORT_UCP */
}
else
-#endif /* SUPPORT_UTF8 */
- otherd = fcc[d];
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
}
if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
{
@@ -2224,6 +2389,15 @@
break;
/*-----------------------------------------------------------------*/
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_POSSTARI:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPOSSTARI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
case OP_STAR:
case OP_MINSTAR:
case OP_POSSTAR:
@@ -2234,18 +2408,18 @@
if (clen > 0)
{
unsigned int otherd = NOTACHAR;
- if ((ims & PCRE_CASELESS) != 0)
+ if (caseless)
{
-#ifdef SUPPORT_UTF8
- if (utf8 && d >= 128)
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
{
#ifdef SUPPORT_UCP
otherd = UCD_OTHERCASE(d);
#endif /* SUPPORT_UCP */
}
else
-#endif /* SUPPORT_UTF8 */
- otherd = fcc[d];
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
}
if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
{
@@ -2260,29 +2434,34 @@
break;
/*-----------------------------------------------------------------*/
+ case OP_EXACTI:
+ case OP_NOTEXACTI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
case OP_EXACT:
case OP_NOTEXACT:
count = current_state->count; /* Number already matched */
if (clen > 0)
{
unsigned int otherd = NOTACHAR;
- if ((ims & PCRE_CASELESS) != 0)
+ if (caseless)
{
-#ifdef SUPPORT_UTF8
- if (utf8 && d >= 128)
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
{
#ifdef SUPPORT_UCP
otherd = UCD_OTHERCASE(d);
#endif /* SUPPORT_UCP */
}
else
-#endif /* SUPPORT_UTF8 */
- otherd = fcc[d];
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
}
if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
{
if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + dlen + 3, 0); }
+ { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
else
{ ADD_NEW(state_offset, count); }
}
@@ -2290,29 +2469,38 @@
break;
/*-----------------------------------------------------------------*/
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_POSUPTOI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPOSUPTOI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
case OP_UPTO:
case OP_MINUPTO:
case OP_POSUPTO:
case OP_NOTUPTO:
case OP_NOTMINUPTO:
case OP_NOTPOSUPTO:
- ADD_ACTIVE(state_offset + dlen + 3, 0);
+ ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0);
count = current_state->count; /* Number already matched */
if (clen > 0)
{
unsigned int otherd = NOTACHAR;
- if ((ims & PCRE_CASELESS) != 0)
+ if (caseless)
{
-#ifdef SUPPORT_UTF8
- if (utf8 && d >= 128)
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
{
#ifdef SUPPORT_UCP
otherd = UCD_OTHERCASE(d);
#endif /* SUPPORT_UCP */
}
else
-#endif /* SUPPORT_UTF8 */
- otherd = fcc[d];
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
}
if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
{
@@ -2322,7 +2510,7 @@
next_active_state--;
}
if (++count >= GET2(code, 1))
- { ADD_NEW(state_offset + dlen + 3, 0); }
+ { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
else
{ ADD_NEW(state_offset, count); }
}
@@ -2339,18 +2527,18 @@
{
BOOL isinclass = FALSE;
int next_state_offset;
- const uschar *ecode;
+ const pcre_uchar *ecode;
/* For a simple class, there is always just a 32-byte table, and we
can set isinclass from it. */
if (codevalue != OP_XCLASS)
{
- ecode = code + 33;
+ ecode = code + 1 + (32 / sizeof(pcre_uchar));
if (clen > 0)
{
isinclass = (c > 255)? (codevalue == OP_NCLASS) :
- ((code[1 + c/8] & (1 << (c&7))) != 0);
+ ((((pcre_uint8 *)(code + 1))[c/8] & (1 << (c&7))) != 0);
}
}
@@ -2361,7 +2549,7 @@
else
{
ecode = code + GET(code, 1);
- if (clen > 0) isinclass = _pcre_xclass(c, code + 1 + LINK_SIZE);
+ if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf);
}
/* At this point, isinclass is set for all kinds of class, and ecode
@@ -2395,12 +2583,12 @@
case OP_CRMINRANGE:
count = current_state->count; /* Already matched */
if (count >= GET2(ecode, 1))
- { ADD_ACTIVE(next_state_offset + 5, 0); }
+ { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
if (isinclass)
{
- int max = GET2(ecode, 3);
+ int max = GET2(ecode, 1 + IMM2_SIZE);
if (++count >= max && max != 0) /* Max 0 => no limit */
- { ADD_NEW(next_state_offset + 5, 0); }
+ { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
else
{ ADD_NEW(state_offset, count); }
}
@@ -2431,7 +2619,7 @@
int rc;
int local_offsets[2];
int local_workspace[1000];
- const uschar *endasscode = code + GET(code, 1);
+ const pcre_uchar *endasscode = code + GET(code, 1);
while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
@@ -2444,9 +2632,7 @@
sizeof(local_offsets)/sizeof(int), /* size of same */
local_workspace, /* workspace vector */
sizeof(local_workspace)/sizeof(int), /* size of same */
- ims, /* the current ims flags */
- rlevel, /* function recursion level */
- recursing); /* pass on regex recursion */
+ rlevel); /* function recursion level */
if (rc == PCRE_ERROR_DFA_UITEM) return rc;
if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))
@@ -2470,13 +2656,17 @@
if (code[LINK_SIZE+1] == OP_CALLOUT)
{
rrc = 0;
- if (pcre_callout != NULL)
+ if (PUBL(callout) != NULL)
{
- pcre_callout_block cb;
+ PUBL(callout_block) cb;
cb.version = 1; /* Version 1 of the callout block */
cb.callout_number = code[LINK_SIZE+2];
cb.offset_vector = offsets;
+#ifdef COMPILE_PCRE8
cb.subject = (PCRE_SPTR)start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)start_subject;
+#endif
cb.subject_length = (int)(end_subject - start_subject);
cb.start_match = (int)(current_subject - start_subject);
cb.current_position = (int)(ptr - start_subject);
@@ -2485,10 +2675,11 @@
cb.capture_top = 1;
cb.capture_last = -1;
cb.callout_data = md->callout_data;
- if ((rrc = (*pcre_callout)(&cb)) < 0) return rrc; /* Abandon */
+ cb.mark = NULL; /* No (*MARK) support */
+ if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */
}
if (rrc > 0) break; /* Fail this thread */
- code += _pcre_OP_lengths[OP_CALLOUT]; /* Skip callout data */
+ code += PRIV(OP_lengths)[OP_CALLOUT]; /* Skip callout data */
}
condcode = code[LINK_SIZE+1];
@@ -2509,10 +2700,10 @@
else if (condcode == OP_RREF || condcode == OP_NRREF)
{
- int value = GET2(code, LINK_SIZE+2);
+ int value = GET2(code, LINK_SIZE + 2);
if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;
- if (recursing > 0)
- { ADD_ACTIVE(state_offset + LINK_SIZE + 4, 0); }
+ if (md->recursive != NULL)
+ { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); }
else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
}
@@ -2521,8 +2712,8 @@
else
{
int rc;
- const uschar *asscode = code + LINK_SIZE + 1;
- const uschar *endasscode = asscode + GET(asscode, 1);
+ const pcre_uchar *asscode = code + LINK_SIZE + 1;
+ const pcre_uchar *endasscode = asscode + GET(asscode, 1);
while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
@@ -2535,9 +2726,7 @@
sizeof(local_offsets)/sizeof(int), /* size of same */
local_workspace, /* workspace vector */
sizeof(local_workspace)/sizeof(int), /* size of same */
- ims, /* the current ims flags */
- rlevel, /* function recursion level */
- recursing); /* pass on regex recursion */
+ rlevel); /* function recursion level */
if (rc == PCRE_ERROR_DFA_UITEM) return rc;
if ((rc >= 0) ==
@@ -2552,28 +2741,47 @@
/*-----------------------------------------------------------------*/
case OP_RECURSE:
{
+ dfa_recursion_info *ri;
int local_offsets[1000];
int local_workspace[1000];
+ const pcre_uchar *callpat = start_code + GET(code, 1);
+ int recno = (callpat == md->start_code)? 0 :
+ GET2(callpat, 1 + LINK_SIZE);
int rc;
- DPRINTF(("%.*sStarting regex recursion %d\n", rlevel*2-2, SP,
- recursing + 1));
+ DPRINTF(("%.*sStarting regex recursion\n", rlevel*2-2, SP));
+
+ /* Check for repeating a recursion without advancing the subject
+ pointer. This should catch convoluted mutual recursions. (Some simple
+ cases are caught at compile time.) */
+
+ for (ri = md->recursive; ri != NULL; ri = ri->prevrec)
+ if (recno == ri->group_num && ptr == ri->subject_position)
+ return PCRE_ERROR_RECURSELOOP;
+
+ /* Remember this recursion and where we started it so as to
+ catch infinite loops. */
+
+ new_recursive.group_num = recno;
+ new_recursive.subject_position = ptr;
+ new_recursive.prevrec = md->recursive;
+ md->recursive = &new_recursive;
rc = internal_dfa_exec(
md, /* fixed match data */
- start_code + GET(code, 1), /* this subexpression's code */
+ callpat, /* this subexpression's code */
ptr, /* where we currently are */
(int)(ptr - start_subject), /* start offset */
local_offsets, /* offset vector */
sizeof(local_offsets)/sizeof(int), /* size of same */
local_workspace, /* workspace vector */
sizeof(local_workspace)/sizeof(int), /* size of same */
- ims, /* the current ims flags */
- rlevel, /* function recursion level */
- recursing + 1); /* regex recurse level */
+ rlevel); /* function recursion level */
+
+ md->recursive = new_recursive.prevrec; /* Done this recursion */
- DPRINTF(("%.*sReturn from regex recursion %d: rc=%d\n", rlevel*2-2, SP,
- recursing + 1, rc));
+ DPRINTF(("%.*sReturn from regex recursion: rc=%d\n", rlevel*2-2, SP,
+ rc));
/* Ran out of internal offsets */
@@ -2587,10 +2795,15 @@
{
for (rc = rc*2 - 2; rc >= 0; rc -= 2)
{
- const uschar *p = start_subject + local_offsets[rc];
- const uschar *pp = start_subject + local_offsets[rc+1];
int charcount = local_offsets[rc+1] - local_offsets[rc];
- while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ const pcre_uchar *p = start_subject + local_offsets[rc];
+ const pcre_uchar *pp = start_subject + local_offsets[rc+1];
+ while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
+ }
+#endif
if (charcount > 0)
{
ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1));
@@ -2606,7 +2819,99 @@
break;
/*-----------------------------------------------------------------*/
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ {
+ int charcount, matched_count;
+ const pcre_uchar *local_ptr = ptr;
+ BOOL allow_zero;
+
+ if (codevalue == OP_BRAPOSZERO)
+ {
+ allow_zero = TRUE;
+ codevalue = *(++code); /* Codevalue will be one of above BRAs */
+ }
+ else allow_zero = FALSE;
+
+ /* Loop to match the subpattern as many times as possible as if it were
+ a complete pattern. */
+
+ for (matched_count = 0;; matched_count++)
+ {
+ int local_offsets[2];
+ int local_workspace[1000];
+
+ int rc = internal_dfa_exec(
+ md, /* fixed match data */
+ code, /* this subexpression's code */
+ local_ptr, /* where we currently are */
+ (int)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(int), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ /* Failed to match */
+
+ if (rc < 0)
+ {
+ if (rc != PCRE_ERROR_NOMATCH) return rc;
+ break;
+ }
+
+ /* Matched: break the loop if zero characters matched. */
+
+ charcount = local_offsets[1] - local_offsets[0];
+ if (charcount == 0) break;
+ local_ptr += charcount; /* Advance temporary position ptr */
+ }
+
+ /* At this point we have matched the subpattern matched_count
+ times, and local_ptr is pointing to the character after the end of the
+ last match. */
+
+ if (matched_count > 0 || allow_zero)
+ {
+ const pcre_uchar *end_subpattern = code;
+ int next_state_offset;
+
+ do { end_subpattern += GET(end_subpattern, 1); }
+ while (*end_subpattern == OP_ALT);
+ next_state_offset =
+ (int)(end_subpattern - start_code + LINK_SIZE + 1);
+
+ /* Optimization: if there are no more active states, and there
+ are no new states yet set up, then skip over the subject string
+ right here, to save looping. Otherwise, set up the new state to swing
+ into action when the end of the matched substring is reached. */
+
+ if (i + 1 >= active_count && new_count == 0)
+ {
+ ptr = local_ptr;
+ clen = 0;
+ ADD_NEW(next_state_offset, 0);
+ }
+ else
+ {
+ const pcre_uchar *p = ptr;
+ const pcre_uchar *pp = local_ptr;
+ charcount = (int)(pp - p);
+#ifdef SUPPORT_UTF
+ if (utf) while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
+#endif
+ ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
+ }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
case OP_ONCE:
+ case OP_ONCE_NC:
{
int local_offsets[2];
int local_workspace[1000];
@@ -2620,13 +2925,11 @@
sizeof(local_offsets)/sizeof(int), /* size of same */
local_workspace, /* workspace vector */
sizeof(local_workspace)/sizeof(int), /* size of same */
- ims, /* the current ims flags */
- rlevel, /* function recursion level */
- recursing); /* pass on regex recursion */
+ rlevel); /* function recursion level */
if (rc >= 0)
{
- const uschar *end_subpattern = code;
+ const pcre_uchar *end_subpattern = code;
int charcount = local_offsets[1] - local_offsets[0];
int next_state_offset, repeat_state_offset;
@@ -2656,7 +2959,7 @@
/* Optimization: if there are no more active states, and there
are no new states yet set up, then skip over the subject string
right here, to save looping. Otherwise, set up the new state to swing
- into action when the end of the substring is reached. */
+ into action when the end of the matched substring is reached. */
else if (i + 1 >= active_count && new_count == 0)
{
@@ -2679,14 +2982,18 @@
}
else
{
- const uschar *p = start_subject + local_offsets[0];
- const uschar *pp = start_subject + local_offsets[1];
- while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ const pcre_uchar *p = start_subject + local_offsets[0];
+ const pcre_uchar *pp = start_subject + local_offsets[1];
+ while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
+ }
+#endif
ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
if (repeat_state_offset >= 0)
{ ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); }
}
-
}
else if (rc != PCRE_ERROR_NOMATCH) return rc;
}
@@ -2698,13 +3005,17 @@
case OP_CALLOUT:
rrc = 0;
- if (pcre_callout != NULL)
+ if (PUBL(callout) != NULL)
{
- pcre_callout_block cb;
+ PUBL(callout_block) cb;
cb.version = 1; /* Version 1 of the callout block */
cb.callout_number = code[1];
cb.offset_vector = offsets;
+#ifdef COMPILE_PCRE8
cb.subject = (PCRE_SPTR)start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)start_subject;
+#endif
cb.subject_length = (int)(end_subject - start_subject);
cb.start_match = (int)(current_subject - start_subject);
cb.current_position = (int)(ptr - start_subject);
@@ -2713,10 +3024,11 @@
cb.capture_top = 1;
cb.capture_last = -1;
cb.callout_data = md->callout_data;
- if ((rrc = (*pcre_callout)(&cb)) < 0) return rrc; /* Abandon */
+ cb.mark = NULL; /* No (*MARK) support */
+ if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */
}
if (rrc == 0)
- { ADD_ACTIVE(state_offset + _pcre_OP_lengths[OP_CALLOUT], 0); }
+ { ADD_ACTIVE(state_offset + PRIV(OP_lengths)[OP_CALLOUT], 0); }
break;
@@ -2745,7 +3057,7 @@
if (new_count <= 0)
{
if (rlevel == 1 && /* Top level, and */
- could_continue && /* Some could go on */
+ could_continue && /* Some could go on, and */
forced_fail != workspace[1] && /* Not all forced fail & */
( /* either... */
(md->moptions & PCRE_PARTIAL_HARD) != 0 /* Hard partial */
@@ -2753,8 +3065,13 @@
((md->moptions & PCRE_PARTIAL_SOFT) != 0 && /* Soft partial and */
match_count < 0) /* no matches */
) && /* And... */
- ptr >= end_subject && /* Reached end of subject */
- ptr > md->start_used_ptr) /* Inspected non-empty string */
+ (
+ partial_newline || /* Either partial NL */
+ ( /* or ... */
+ ptr >= end_subject && /* End of subject and */
+ ptr > md->start_used_ptr) /* Inspected non-empty string */
+ )
+ )
{
if (offsetcount >= 2)
{
@@ -2813,28 +3130,33 @@
< -1 => some kind of unexpected problem
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,
const char *subject, int length, int start_offset, int options, int *offsets,
int offsetcount, int *workspace, int wscount)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
+ PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
+ int offsetcount, int *workspace, int wscount)
+#endif
{
-real_pcre *re = (real_pcre *)argument_re;
+REAL_PCRE *re = (REAL_PCRE *)argument_re;
dfa_match_data match_block;
dfa_match_data *md = &match_block;
-BOOL utf8, anchored, startline, firstline;
-const uschar *current_subject, *end_subject, *lcc;
-
-pcre_study_data internal_study;
+BOOL utf, anchored, startline, firstline;
+const pcre_uchar *current_subject, *end_subject;
const pcre_study_data *study = NULL;
-real_pcre internal_re;
-const uschar *req_byte_ptr;
-const uschar *start_bits = NULL;
-BOOL first_byte_caseless = FALSE;
-BOOL req_byte_caseless = FALSE;
-int first_byte = -1;
-int req_byte = -1;
-int req_byte2 = -1;
+const pcre_uchar *req_char_ptr;
+const pcre_uint8 *start_bits = NULL;
+BOOL has_first_char = FALSE;
+BOOL has_req_char = FALSE;
+pcre_uchar first_char = 0;
+pcre_uchar first_char2 = 0;
+pcre_uchar req_char = 0;
+pcre_uchar req_char2 = 0;
int newline;
/* Plausibility checks */
@@ -2846,10 +3168,27 @@
if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
-/* We need to find the pointer to any study data before we test for byte
-flipping, so we scan the extra_data block first. This may set two fields in the
-match block, so we must initialize them beforehand. However, the other fields
-in the match block must not be set until after the byte flipping. */
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
+REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
+means that the pattern is likely compiled with different endianness. */
+
+if (re->magic_number != MAGIC_NUMBER)
+ return re->magic_number == REVERSED_MAGIC_NUMBER?
+ PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
+/* If restarting after a partial match, do some sanity checks on the contents
+of the workspace. */
+
+if ((options & PCRE_DFA_RESTART) != 0)
+ {
+ if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||
+ workspace[1] > (wscount - 2)/INTS_PER_STATEBLOCK)
+ return PCRE_ERROR_DFA_BADRESTART;
+ }
+
+/* Set up study, callout, and table data */
md->tables = re->tables;
md->callout_data = NULL;
@@ -2868,28 +3207,17 @@
md->tables = extra_data->tables;
}
-/* Check that the first field in the block is the magic number. If it is not,
-test for a regex that was compiled on a host of opposite endianness. If this is
-the case, flipped values are put in internal_re and internal_study if there was
-study data too. */
-
-if (re->magic_number != MAGIC_NUMBER)
- {
- re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
- if (re == NULL) return PCRE_ERROR_BADMAGIC;
- if (study != NULL) study = &internal_study;
- }
-
/* Set some local values */
-current_subject = (const unsigned char *)subject + start_offset;
-end_subject = (const unsigned char *)subject + length;
-req_byte_ptr = current_subject - 1;
-
-#ifdef SUPPORT_UTF8
-utf8 = (re->options & PCRE_UTF8) != 0;
+current_subject = (const pcre_uchar *)subject + start_offset;
+end_subject = (const pcre_uchar *)subject + length;
+req_char_ptr = current_subject - 1;
+
+#ifdef SUPPORT_UTF
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+utf = (re->options & PCRE_UTF8) != 0;
#else
-utf8 = FALSE;
+utf = FALSE;
#endif
anchored = (options & (PCRE_ANCHORED|PCRE_DFA_RESTART)) != 0 ||
@@ -2897,9 +3225,9 @@
/* The remaining fixed data for passing around. */
-md->start_code = (const uschar *)argument_re +
+md->start_code = (const pcre_uchar *)argument_re +
re->name_table_offset + re->name_count * re->name_entry_size;
-md->start_subject = (const unsigned char *)subject;
+md->start_subject = (const pcre_uchar *)subject;
md->end_subject = end_subject;
md->start_offset = start_offset;
md->moptions = options;
@@ -2960,18 +3288,24 @@
/* Check a UTF-8 string if required. Unfortunately there's no way of passing
back the character offset. */
-#ifdef SUPPORT_UTF8
-if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
+#ifdef SUPPORT_UTF
+if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
{
- int tb;
- if ((tb = _pcre_valid_utf8((uschar *)subject, length)) >= 0)
- return (tb == length && (options & PCRE_PARTIAL_HARD) != 0)?
- PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
- if (start_offset > 0 && start_offset < length)
+ int erroroffset;
+ int errorcode = PRIV(valid_utf)((pcre_uchar *)subject, length, &erroroffset);
+ if (errorcode != 0)
{
- tb = ((USPTR)subject)[start_offset] & 0xc0;
- if (tb == 0x80) return PCRE_ERROR_BADUTF8_OFFSET;
+ if (offsetcount >= 2)
+ {
+ offsets[0] = erroroffset;
+ offsets[1] = errorcode;
+ }
+ return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)?
+ PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
}
+ if (start_offset > 0 && start_offset < length &&
+ NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
+ return PCRE_ERROR_BADUTF8_OFFSET;
}
#endif
@@ -2979,12 +3313,11 @@
is a feature that makes it possible to save compiled regex and re-use them
in other programs later. */
-if (md->tables == NULL) md->tables = _pcre_default_tables;
+if (md->tables == NULL) md->tables = PRIV(default_tables);
-/* The lower casing table and the "must be at the start of a line" flag are
-used in a loop when finding where to start. */
+/* The "must be at the start of a line" flags are used in a loop when finding
+where to start. */
-lcc = md->tables + lcc_offset;
startline = (re->flags & PCRE_STARTLINE) != 0;
firstline = (re->options & PCRE_FIRSTLINE) != 0;
@@ -2998,9 +3331,16 @@
{
if ((re->flags & PCRE_FIRSTSET) != 0)
{
- first_byte = re->first_byte & 255;
- if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)
- first_byte = lcc[first_byte];
+ has_first_char = TRUE;
+ first_char = first_char2 = (pcre_uchar)(re->first_char);
+ if ((re->flags & PCRE_FCH_CASELESS) != 0)
+ {
+ first_char2 = TABLE_GET(first_char, md->tables + fcc_offset, first_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && first_char > 127)
+ first_char2 = UCD_OTHERCASE(first_char);
+#endif
+ }
}
else
{
@@ -3015,9 +3355,16 @@
if ((re->flags & PCRE_REQCHSET) != 0)
{
- req_byte = re->req_byte & 255;
- req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;
- req_byte2 = (md->tables + fcc_offset)[req_byte]; /* case flipped */
+ has_req_char = TRUE;
+ req_char = req_char2 = (pcre_uchar)(re->req_char);
+ if ((re->flags & PCRE_RCH_CASELESS) != 0)
+ {
+ req_char2 = TABLE_GET(req_char, md->tables + fcc_offset, req_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && req_char > 127)
+ req_char2 = UCD_OTHERCASE(req_char);
+#endif
+ }
}
/* Call the main matching function, looping for a non-anchored regex after a
@@ -3030,7 +3377,7 @@
if ((options & PCRE_DFA_RESTART) == 0)
{
- const uschar *save_end_subject = end_subject;
+ const pcre_uchar *save_end_subject = end_subject;
/* If firstline is TRUE, the start of the match is constrained to the first
line of a multiline string. Implement this by temporarily adjusting
@@ -3039,14 +3386,14 @@
if (firstline)
{
- USPTR t = current_subject;
-#ifdef SUPPORT_UTF8
- if (utf8)
+ PCRE_PUCHAR t = current_subject;
+#ifdef SUPPORT_UTF
+ if (utf)
{
while (t < md->end_subject && !IS_NEWLINE(t))
{
t++;
- while (t < end_subject && (*t & 0xc0) == 0x80) t++;
+ ACROSSCHAR(t < end_subject, *t, t++);
}
}
else
@@ -3063,17 +3410,17 @@
if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
{
- /* Advance to a known first byte. */
+ /* Advance to a known first char. */
- if (first_byte >= 0)
+ if (has_first_char)
{
- if (first_byte_caseless)
+ if (first_char != first_char2)
while (current_subject < end_subject &&
- lcc[*current_subject] != first_byte)
+ *current_subject != first_char && *current_subject != first_char2)
current_subject++;
else
while (current_subject < end_subject &&
- *current_subject != first_byte)
+ *current_subject != first_char)
current_subject++;
}
@@ -3083,16 +3430,15 @@
{
if (current_subject > md->start_subject + start_offset)
{
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
while (current_subject < end_subject &&
!WAS_NEWLINE(current_subject))
{
current_subject++;
- while(current_subject < end_subject &&
- (*current_subject & 0xc0) == 0x80)
- current_subject++;
+ ACROSSCHAR(current_subject < end_subject, *current_subject,
+ current_subject++);
}
}
else
@@ -3119,13 +3465,18 @@
while (current_subject < end_subject)
{
register unsigned int c = *current_subject;
+#ifndef COMPILE_PCRE8
+ if (c > 255) c = 255;
+#endif
if ((start_bits[c/8] & (1 << (c&7))) == 0)
{
current_subject++;
-#ifdef SUPPORT_UTF8
- if (utf8)
- while(current_subject < end_subject &&
- (*current_subject & 0xc0) == 0x80) current_subject++;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ /* In non 8-bit mode, the iteration will stop for
+ characters > 255 at the beginning or not stop at all. */
+ if (utf)
+ ACROSSCHAR(current_subject < end_subject, *current_subject,
+ current_subject++);
#endif
}
else break;
@@ -3141,7 +3492,7 @@
disabling is explicitly requested (and of course, by the test above, this
code is not obeyed when restarting after a partial match). */
- if ((options & PCRE_NO_START_OPTIMIZE) == 0 &&
+ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 &&
(options & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) == 0)
{
/* If the pattern was studied, a minimum subject length may be set. This
@@ -3153,8 +3504,8 @@
(pcre_uint32)(end_subject - current_subject) < study->minlength)
return PCRE_ERROR_NOMATCH;
- /* If req_byte is set, we know that that character must appear in the
- subject for the match to succeed. If the first character is set, req_byte
+ /* If req_char is set, we know that that character must appear in the
+ subject for the match to succeed. If the first character is set, req_char
must be later in the subject; otherwise the test starts at the match
point. This optimization can save a huge amount of work in patterns with
nested unlimited repeats that aren't going to match. Writing separate
@@ -3166,28 +3517,28 @@
patterns. This showed up when somebody was matching /^C/ on a 32-megabyte
string... so we don't do this when the string is sufficiently long. */
- if (req_byte >= 0 && end_subject - current_subject < REQ_BYTE_MAX)
+ if (has_req_char && end_subject - current_subject < REQ_BYTE_MAX)
{
- register const uschar *p = current_subject + ((first_byte >= 0)? 1 : 0);
+ register PCRE_PUCHAR p = current_subject + (has_first_char? 1:0);
/* We don't need to repeat the search if we haven't yet reached the
place we found it at last time. */
- if (p > req_byte_ptr)
+ if (p > req_char_ptr)
{
- if (req_byte_caseless)
+ if (req_char != req_char2)
{
while (p < end_subject)
{
register int pp = *p++;
- if (pp == req_byte || pp == req_byte2) { p--; break; }
+ if (pp == req_char || pp == req_char2) { p--; break; }
}
}
else
{
while (p < end_subject)
{
- if (*p++ == req_byte) { p--; break; }
+ if (*p++ == req_char) { p--; break; }
}
}
@@ -3200,7 +3551,7 @@
found it, so that we don't search again next time round the loop if
the start hasn't passed this character yet. */
- req_byte_ptr = p;
+ req_char_ptr = p;
}
}
}
@@ -3209,6 +3560,7 @@
/* OK, now we can do the business */
md->start_used_ptr = current_subject;
+ md->recursive = NULL;
rc = internal_dfa_exec(
md, /* fixed match data */
@@ -3219,9 +3571,7 @@
offsetcount, /* size of same */
workspace, /* workspace vector */
wscount, /* size of same */
- re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL), /* ims flags */
- 0, /* function recurse level */
- 0); /* regex recurse level */
+ 0); /* function recurse level */
/* Anything other than "no match" means we are done, always; otherwise, carry
on only if not anchored. */
@@ -3233,11 +3583,13 @@
if (firstline && IS_NEWLINE(current_subject)) break;
current_subject++;
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
- while (current_subject < end_subject && (*current_subject & 0xc0) == 0x80)
- current_subject++;
+ ACROSSCHAR(current_subject < end_subject, *current_subject,
+ current_subject++);
}
+#endif
if (current_subject > end_subject) break;
/* If we have just passed a CR and we are now at a LF, and the pattern does
diff -Nru pcre3-8.12/pcre_exec.c pcre3-8.31/pcre_exec.c
--- pcre3-8.12/pcre_exec.c 2010-11-24 17:38:32.000000000 +0000
+++ pcre3-8.31/pcre_exec.c 2012-06-19 18:32:03.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2010 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -37,7 +37,6 @@
-----------------------------------------------------------------------------
*/
-
/* This module contains pcre_exec(), the externally visible function that does
pattern matching using an NFA algorithm, trying to mimic Perl as closely as
possible. There are also some static supporting functions. */
@@ -57,10 +56,12 @@
#undef min
#undef max
-/* Flag bits for the match() function */
+/* Values for setting in md->match_function_type to indicate two special types
+of call to match(). We do it this way to save on using another stack variable,
+as stack usage is to be discouraged. */
-#define match_condassert 0x01 /* Called to check a condition assertion */
-#define match_cbegroup 0x02 /* Could-be-empty unlimited repeat group */
+#define MATCH_CONDASSERT 1 /* Called to check a condition assertion */
+#define MATCH_CBEGROUP 2 /* Could-be-empty unlimited repeat group */
/* Non-error returns from the match() function. Error returns are externally
defined PCRE_ERROR_xxx codes, which are all negative. */
@@ -73,18 +74,12 @@
#define MATCH_ACCEPT (-999)
#define MATCH_COMMIT (-998)
-#define MATCH_PRUNE (-997)
-#define MATCH_SKIP (-996)
-#define MATCH_SKIP_ARG (-995)
-#define MATCH_THEN (-994)
-
-/* This is a convenience macro for code that occurs many times. */
-
-#define MRRETURN(ra) \
- { \
- md->mark = markptr; \
- RRETURN(ra); \
- }
+#define MATCH_KETRPOS (-997)
+#define MATCH_ONCE (-996)
+#define MATCH_PRUNE (-995)
+#define MATCH_SKIP (-994)
+#define MATCH_SKIP_ARG (-993)
+#define MATCH_THEN (-992)
/* Maximum number of ints of offset to save on the stack for recursive calls.
If the offset vector is bigger, malloc is used. This should be a multiple of 3,
@@ -117,7 +112,7 @@
*/
static void
-pchars(const uschar *p, int length, BOOL is_subject, match_data *md)
+pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md)
{
unsigned int c;
if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
@@ -132,24 +127,29 @@
* Match a back-reference *
*************************************************/
-/* If a back reference hasn't been set, the length that is passed is greater
-than the number of characters left in the string, so the match fails.
+/* Normally, if a back reference hasn't been set, the length that is passed is
+negative, so the match always fails. However, in JavaScript compatibility mode,
+the length passed is zero. Note that in caseless UTF-8 mode, the number of
+subject bytes matched may be different to the number of reference bytes.
Arguments:
offset index into the offset vector
- eptr points into the subject
- length length to be matched
+ eptr pointer into the subject
+ length length of reference to be matched (number of bytes)
md points to match data block
- ims the ims flags
+ caseless TRUE if caseless
-Returns: TRUE if matched
+Returns: >= 0 the number of subject bytes matched
+ -1 no match
+ -2 partial match; always given if at end subject
*/
-static BOOL
-match_ref(int offset, register USPTR eptr, int length, match_data *md,
- unsigned long int ims)
+static int
+match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md,
+ BOOL caseless)
{
-USPTR p = md->start_subject + md->offset_vector[offset];
+PCRE_PUCHAR eptr_start = eptr;
+register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
#ifdef PCRE_DEBUG
if (eptr >= md->end_subject)
@@ -164,27 +164,37 @@
printf("\n");
#endif
-/* Always fail if not enough characters left */
+/* Always fail if reference not set (and not JavaScript compatible - in that
+case the length is passed as zero). */
-if (length > md->end_subject - eptr) return FALSE;
+if (length < 0) return -1;
/* Separate the caseless case for speed. In UTF-8 mode we can only do this
properly if Unicode properties are supported. Otherwise, we can check only
ASCII characters. */
-if ((ims & PCRE_CASELESS) != 0)
+if (caseless)
{
-#ifdef SUPPORT_UTF8
+#ifdef SUPPORT_UTF
#ifdef SUPPORT_UCP
- if (md->utf8)
+ if (md->utf)
{
- USPTR endptr = eptr + length;
- while (eptr < endptr)
+ /* Match characters up to the end of the reference. NOTE: the number of
+ bytes matched may differ, because there are some characters whose upper and
+ lower case versions code as different numbers of bytes. For example, U+023A
+ (2 bytes in UTF-8) is the upper case version of U+2C65 (3 bytes in UTF-8);
+ a sequence of 3 of the former uses 6 bytes, as does a sequence of two of
+ the latter. It is important, therefore, to check the length along the
+ reference, not along the subject (earlier code did this wrong). */
+
+ PCRE_PUCHAR endptr = p + length;
+ while (p < endptr)
{
int c, d;
+ if (eptr >= md->end_subject) return -2; /* Partial match */
GETCHARINC(c, eptr);
GETCHARINC(d, p);
- if (c != d && c != UCD_OTHERCASE(d)) return FALSE;
+ if (c != d && c != UCD_OTHERCASE(d)) return -1;
}
}
else
@@ -193,18 +203,30 @@
/* The same code works when not in UTF-8 mode and in UTF-8 mode when there
is no UCP support. */
-
- while (length-- > 0)
- { if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; }
+ {
+ while (length-- > 0)
+ {
+ if (eptr >= md->end_subject) return -2; /* Partial match */
+ if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;
+ p++;
+ eptr++;
+ }
+ }
}
/* In the caseful case, we can just compare the bytes, whether or not we
are in UTF-8 mode. */
else
- { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }
+ {
+ while (length-- > 0)
+ {
+ if (eptr >= md->end_subject) return -2; /* Partial match */
+ if (*p++ != *eptr++) return -1;
+ }
+ }
-return TRUE;
+return (int)(eptr - eptr_start);
}
@@ -256,7 +278,7 @@
RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
- RM61, RM62 };
+ RM61, RM62, RM63, RM64, RM65, RM66 };
/* These versions of the macros use the stack, as normal. There are debugging
versions and production versions. Note that the "rw" argument of RMATCH isn't
@@ -266,10 +288,10 @@
#define REGISTER register
#ifdef PCRE_DEBUG
-#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
+#define RMATCH(ra,rb,rc,rd,re,rw) \
{ \
printf("match() called in line %d\n", __LINE__); \
- rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1); \
+ rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \
printf("to line %d\n", __LINE__); \
}
#define RRETURN(ra) \
@@ -278,8 +300,8 @@
return ra; \
}
#else
-#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
- rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1)
+#define RMATCH(ra,rb,rc,rd,re,rw) \
+ rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1)
#define RRETURN(ra) return ra
#endif
@@ -292,19 +314,22 @@
#define REGISTER
-#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
+#define RMATCH(ra,rb,rc,rd,re,rw)\
{\
- heapframe *newframe = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));\
- if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
- frame->Xwhere = rw; \
+ heapframe *newframe = frame->Xnextframe;\
+ if (newframe == NULL)\
+ {\
+ newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
+ if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
+ newframe->Xnextframe = NULL;\
+ frame->Xnextframe = newframe;\
+ }\
+ frame->Xwhere = rw;\
newframe->Xeptr = ra;\
newframe->Xecode = rb;\
newframe->Xmstart = mstart;\
- newframe->Xmarkptr = markptr;\
newframe->Xoffset_top = rc;\
- newframe->Xims = re;\
- newframe->Xeptrb = rf;\
- newframe->Xflags = rg;\
+ newframe->Xeptrb = re;\
newframe->Xrdepth = frame->Xrdepth + 1;\
newframe->Xprevframe = frame;\
frame = newframe;\
@@ -318,7 +343,6 @@
{\
heapframe *oldframe = frame;\
frame = oldframe->Xprevframe;\
- (pcre_stack_free)(oldframe);\
if (frame != NULL)\
{\
rrc = ra;\
@@ -332,30 +356,28 @@
typedef struct heapframe {
struct heapframe *Xprevframe;
+ struct heapframe *Xnextframe;
/* Function arguments that may change */
- USPTR Xeptr;
- const uschar *Xecode;
- USPTR Xmstart;
- USPTR Xmarkptr;
+ PCRE_PUCHAR Xeptr;
+ const pcre_uchar *Xecode;
+ PCRE_PUCHAR Xmstart;
int Xoffset_top;
- long int Xims;
eptrblock *Xeptrb;
- int Xflags;
unsigned int Xrdepth;
/* Function local variables */
- USPTR Xcallpat;
-#ifdef SUPPORT_UTF8
- USPTR Xcharptr;
-#endif
- USPTR Xdata;
- USPTR Xnext;
- USPTR Xpp;
- USPTR Xprev;
- USPTR Xsaved_eptr;
+ PCRE_PUCHAR Xcallpat;
+#ifdef SUPPORT_UTF
+ PCRE_PUCHAR Xcharptr;
+#endif
+ PCRE_PUCHAR Xdata;
+ PCRE_PUCHAR Xnext;
+ PCRE_PUCHAR Xpp;
+ PCRE_PUCHAR Xprev;
+ PCRE_PUCHAR Xsaved_eptr;
recursion_info Xnew_recursive;
@@ -363,17 +385,12 @@
BOOL Xcondition;
BOOL Xprev_is_word;
- unsigned long int Xoriginal_ims;
-
#ifdef SUPPORT_UCP
int Xprop_type;
int Xprop_value;
int Xprop_fail_result;
- int Xprop_category;
- int Xprop_chartype;
- int Xprop_script;
int Xoclength;
- uschar Xocchars[8];
+ pcre_uchar Xocchars[6];
#endif
int Xcodelink;
@@ -415,7 +432,7 @@
same response. */
/* These macros pack up tests that are used for partial matching, and which
-appears several times in the code. We set the "hit end" flag if the pointer is
+appear several times in the code. We set the "hit end" flag if the pointer is
at the end of the subject and also past the start of the subject (i.e.
something has been matched). For hard partial matching, we then return
immediately. The second one is used when we already know we are past the end of
@@ -426,19 +443,19 @@
eptr > md->start_used_ptr) \
{ \
md->hitend = TRUE; \
- if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
}
#define SCHECK_PARTIAL()\
if (md->partial != 0 && eptr > md->start_used_ptr) \
{ \
md->hitend = TRUE; \
- if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
}
/* Performance note: It might be tempting to extract commonly used fields from
-the md structure (e.g. utf8, end_subject) into individual variables to improve
+the md structure (e.g. utf, end_subject) into individual variables to improve
performance. Tests using gcc on a SPARC disproved this; in the first case, it
made performance worse.
@@ -447,16 +464,10 @@
ecode pointer to current position in compiled code
mstart pointer to the current match start position (can be modified
by encountering \K)
- markptr pointer to the most recent MARK name, or NULL
offset_top current top pointer
md pointer to "static" info for the match
- ims current /i, /m, and /s options
eptrb pointer to chain of blocks containing eptr at start of
brackets - for testing for empty matches
- flags can contain
- match_condassert - this is an assertion condition
- match_cbegroup - this is the start of an unlimited repeat
- group that can match an empty string
rdepth the recursion depth
Returns: MATCH_MATCH if matched ) these values are >= 0
@@ -467,9 +478,9 @@
*/
static int
-match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,
- const uschar *markptr, int offset_top, match_data *md, unsigned long int ims,
- eptrblock *eptrb, int flags, unsigned int rdepth)
+match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
+ PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
+ unsigned int rdepth)
{
/* These variables do not need to be preserved over recursion in this function,
so they can be ordinary variables in all cases. Mark some of them with
@@ -478,31 +489,29 @@
register int rrc; /* Returns from recursive calls */
register int i; /* Used for loops not involving calls to RMATCH() */
register unsigned int c; /* Character values not kept over RMATCH() calls */
-register BOOL utf8; /* Local copy of UTF-8 flag for speed */
+register BOOL utf; /* Local copy of UTF flag for speed */
BOOL minimize, possessive; /* Quantifier options */
+BOOL caseless;
int condcode;
/* When recursion is not being used, all "local" variables that have to be
-preserved over calls to RMATCH() are part of a "frame" which is obtained from
-heap storage. Set up the top-level frame here; others are obtained from the
-heap whenever RMATCH() does a "recursion". See the macro definitions above. */
+preserved over calls to RMATCH() are part of a "frame". We set up the top-level
+frame on the stack here; subsequent instantiations are obtained from the heap
+whenever RMATCH() does a "recursion". See the macro definitions above. Putting
+the top-level on the stack rather than malloc-ing them all gives a performance
+boost in many cases where there is not much "recursion". */
#ifdef NO_RECURSE
-heapframe *frame = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));
-if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
-frame->Xprevframe = NULL; /* Marks the top level */
+heapframe *frame = (heapframe *)md->match_frames_base;
/* Copy in the original argument variables */
frame->Xeptr = eptr;
frame->Xecode = ecode;
frame->Xmstart = mstart;
-frame->Xmarkptr = markptr;
frame->Xoffset_top = offset_top;
-frame->Xims = ims;
frame->Xeptrb = eptrb;
-frame->Xflags = flags;
frame->Xrdepth = rdepth;
/* This is where control jumps back to to effect "recursion" */
@@ -514,16 +523,13 @@
#define eptr frame->Xeptr
#define ecode frame->Xecode
#define mstart frame->Xmstart
-#define markptr frame->Xmarkptr
#define offset_top frame->Xoffset_top
-#define ims frame->Xims
#define eptrb frame->Xeptrb
-#define flags frame->Xflags
#define rdepth frame->Xrdepth
/* Ditto for the local variables */
-#ifdef SUPPORT_UTF8
+#ifdef SUPPORT_UTF
#define charptr frame->Xcharptr
#endif
#define callpat frame->Xcallpat
@@ -540,15 +546,10 @@
#define condition frame->Xcondition
#define prev_is_word frame->Xprev_is_word
-#define original_ims frame->Xoriginal_ims
-
#ifdef SUPPORT_UCP
#define prop_type frame->Xprop_type
#define prop_value frame->Xprop_value
#define prop_fail_result frame->Xprop_fail_result
-#define prop_category frame->Xprop_category
-#define prop_chartype frame->Xprop_chartype
-#define prop_script frame->Xprop_script
#define oclength frame->Xoclength
#define occhars frame->Xocchars
#endif
@@ -578,34 +579,36 @@
#define fi i
#define fc c
+/* Many of the following variables are used only in small blocks of the code.
+My normal style of coding would have declared them within each of those blocks.
+However, in order to accommodate the version of this code that uses an external
+"stack" implemented on the heap, it is easier to declare them all here, so the
+declarations can be cut out in a block. The only declarations within blocks
+below are for variables that do not have to be preserved over a recursive call
+to RMATCH(). */
+
+#ifdef SUPPORT_UTF
+const pcre_uchar *charptr;
+#endif
+const pcre_uchar *callpat;
+const pcre_uchar *data;
+const pcre_uchar *next;
+PCRE_PUCHAR pp;
+const pcre_uchar *prev;
+PCRE_PUCHAR saved_eptr;
+
+recursion_info new_recursive;
-#ifdef SUPPORT_UTF8 /* Many of these variables are used only */
-const uschar *charptr; /* in small blocks of the code. My normal */
-#endif /* style of coding would have declared */
-const uschar *callpat; /* them within each of those blocks. */
-const uschar *data; /* However, in order to accommodate the */
-const uschar *next; /* version of this code that uses an */
-USPTR pp; /* external "stack" implemented on the */
-const uschar *prev; /* heap, it is easier to declare them all */
-USPTR saved_eptr; /* here, so the declarations can be cut */
- /* out in a block. The only declarations */
-recursion_info new_recursive; /* within blocks below are for variables */
- /* that do not have to be preserved over */
-BOOL cur_is_word; /* a recursive call to RMATCH(). */
+BOOL cur_is_word;
BOOL condition;
BOOL prev_is_word;
-unsigned long int original_ims;
-
#ifdef SUPPORT_UCP
int prop_type;
int prop_value;
int prop_fail_result;
-int prop_category;
-int prop_chartype;
-int prop_script;
int oclength;
-uschar occhars[8];
+pcre_uchar occhars[6];
#endif
int codelink;
@@ -621,8 +624,38 @@
int stacksave[REC_STACK_SAVE_MAX];
eptrblock newptrb;
+
+/* There is a special fudge for calling match() in a way that causes it to
+measure the size of its basic stack frame when the stack is being used for
+recursion. The second argument (ecode) being NULL triggers this behaviour. It
+cannot normally ever be NULL. The return is the negated value of the frame
+size. */
+
+if (ecode == NULL)
+ {
+ if (rdepth == 0)
+ return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
+ else
+ {
+ int len = (char *)&rdepth - (char *)eptr;
+ return (len > 0)? -len : len;
+ }
+ }
#endif /* NO_RECURSE */
+/* To save space on the stack and in the heap frame, I have doubled up on some
+of the local variables that are used only in localised parts of the code, but
+still need to be preserved over recursive calls of match(). These macros define
+the alternative names that are used. */
+
+#define allow_zero cur_is_word
+#define cbegroup condition
+#define code_offset codelink
+#define condassert condition
+#define matched_once prev_is_word
+#define foc number
+#define save_mark data
+
/* These statements are here to stop the compiler complaining about unitialized
variables. */
@@ -647,10 +680,10 @@
complicated macro. It has to be used in one particular way. This shouldn't,
however, impact performance when true recursion is being used. */
-#ifdef SUPPORT_UTF8
-utf8 = md->utf8; /* Local copy of the flag */
+#ifdef SUPPORT_UTF
+utf = md->utf; /* Local copy of the flag */
#else
-utf8 = FALSE;
+utf = FALSE;
#endif
/* First check that we haven't called match() too many times, or that we
@@ -659,22 +692,24 @@
if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT);
if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
-original_ims = ims; /* Save for resetting on ')' */
-
/* At the start of a group with an unlimited repeat that may match an empty
-string, the match_cbegroup flag is set. When this is the case, add the current
-subject pointer to the chain of such remembered pointers, to be checked when we
-hit the closing ket, in order to break infinite loops that match no characters.
-When match() is called in other circumstances, don't add to the chain. The
-match_cbegroup flag must NOT be used with tail recursion, because the memory
-block that is used is on the stack, so a new one may be required for each
-match(). */
+string, the variable md->match_function_type is set to MATCH_CBEGROUP. It is
+done this way to save having to use another function argument, which would take
+up space on the stack. See also MATCH_CONDASSERT below.
+
+When MATCH_CBEGROUP is set, add the current subject pointer to the chain of
+such remembered pointers, to be checked when we hit the closing ket, in order
+to break infinite loops that match no characters. When match() is called in
+other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must
+NOT be used with tail recursion, because the memory block that is used is on
+the stack, so a new one may be required for each match(). */
-if ((flags & match_cbegroup) != 0)
+if (md->match_function_type == MATCH_CBEGROUP)
{
newptrb.epb_saved_eptr = eptr;
newptrb.epb_prev = eptrb;
eptrb = &newptrb;
+ md->match_function_type = 0;
}
/* Now start processing the opcodes. */
@@ -687,9 +722,12 @@
switch(op)
{
case OP_MARK:
- markptr = ecode + 2;
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
- ims, eptrb, flags, RM55);
+ md->nomatch_mark = ecode + 2;
+ md->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
+ eptrb, RM55);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ md->mark == NULL) md->mark = ecode + 2;
/* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
argument, and we must check whether that argument matches this MARK's
@@ -698,98 +736,192 @@
position and return MATCH_SKIP. Otherwise, pass back the return code
unaltered. */
- if (rrc == MATCH_SKIP_ARG &&
- strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)
+ else if (rrc == MATCH_SKIP_ARG &&
+ STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)
{
md->start_match_ptr = eptr;
RRETURN(MATCH_SKIP);
}
-
- if (md->mark == NULL) md->mark = markptr;
RRETURN(rrc);
case OP_FAIL:
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
/* COMMIT overrides PRUNE, SKIP, and THEN */
case OP_COMMIT:
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags, RM52);
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM52);
if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
rrc != MATCH_THEN)
RRETURN(rrc);
- MRRETURN(MATCH_COMMIT);
+ RRETURN(MATCH_COMMIT);
/* PRUNE overrides THEN */
case OP_PRUNE:
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags, RM51);
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM51);
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- MRRETURN(MATCH_PRUNE);
+ RRETURN(MATCH_PRUNE);
case OP_PRUNE_ARG:
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
- ims, eptrb, flags, RM56);
+ md->nomatch_mark = ecode + 2;
+ md->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
+ eptrb, RM56);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ md->mark == NULL) md->mark = ecode + 2;
if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
- md->mark = ecode + 2;
RRETURN(MATCH_PRUNE);
/* SKIP overrides PRUNE and THEN */
case OP_SKIP:
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags, RM53);
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM53);
if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
RRETURN(rrc);
md->start_match_ptr = eptr; /* Pass back current position */
- MRRETURN(MATCH_SKIP);
+ RRETURN(MATCH_SKIP);
+
+ /* Note that, for Perl compatibility, SKIP with an argument does NOT set
+ nomatch_mark. There is a flag that disables this opcode when re-matching a
+ pattern that ended with a SKIP for which there was not a matching MARK. */
case OP_SKIP_ARG:
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
- ims, eptrb, flags, RM57);
+ if (md->ignore_skip_arg)
+ {
+ ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
+ break;
+ }
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
+ eptrb, RM57);
if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
RRETURN(rrc);
/* Pass back the current skip name by overloading md->start_match_ptr and
returning the special MATCH_SKIP_ARG return code. This will either be
- caught by a matching MARK, or get to the top, where it is treated the same
- as PRUNE. */
+ caught by a matching MARK, or get to the top, where it causes a rematch
+ with the md->ignore_skip_arg flag set. */
md->start_match_ptr = ecode + 2;
RRETURN(MATCH_SKIP_ARG);
- /* For THEN (and THEN_ARG) we pass back the address of the bracket or
- the alt that is at the start of the current branch. This makes it possible
- to skip back past alternatives that precede the THEN within the current
- branch. */
+ /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that
+ the branch in which it occurs can be determined. Overload the start of
+ match pointer to do this. */
case OP_THEN:
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags, RM54);
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM54);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->start_match_ptr = ecode - GET(ecode, 1);
- MRRETURN(MATCH_THEN);
+ md->start_match_ptr = ecode;
+ RRETURN(MATCH_THEN);
case OP_THEN_ARG:
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1+LINK_SIZE],
- offset_top, md, ims, eptrb, flags, RM58);
+ md->nomatch_mark = ecode + 2;
+ md->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
+ md, eptrb, RM58);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ md->mark == NULL) md->mark = ecode + 2;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->start_match_ptr = ecode - GET(ecode, 1);
- md->mark = ecode + LINK_SIZE + 2;
+ md->start_match_ptr = ecode;
RRETURN(MATCH_THEN);
- /* Handle a capturing bracket. If there is space in the offset vector, save
- the current subject position in the working slot at the top of the vector.
- We mustn't change the current values of the data slot, because they may be
- set from a previous iteration of this group, and be referred to by a
- reference inside the group.
-
- If the bracket fails to match, we need to restore this value and also the
- values of the final offsets, in case they were set by a previous iteration
- of the same bracket.
+ /* Handle an atomic group that does not contain any capturing parentheses.
+ This can be handled like an assertion. Prior to 8.13, all atomic groups
+ were handled this way. In 8.13, the code was changed as below for ONCE, so
+ that backups pass through the group and thereby reset captured values.
+ However, this uses a lot more stack, so in 8.20, atomic groups that do not
+ contain any captures generate OP_ONCE_NC, which can be handled in the old,
+ less stack intensive way.
+
+ Check the alternative branches in turn - the matching won't pass the KET
+ for this kind of subpattern. If any one branch matches, we carry on as at
+ the end of a normal bracket, leaving the subject pointer, but resetting
+ the start-of-match value in case it was changed by \K. */
+
+ case OP_ONCE_NC:
+ prev = ecode;
+ saved_eptr = eptr;
+ save_mark = md->mark;
+ do
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);
+ if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */
+ {
+ mstart = md->start_match_ptr;
+ break;
+ }
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += GET(ecode,1);
+ md->mark = save_mark;
+ }
+ while (*ecode == OP_ALT);
+
+ /* If hit the end of the group (which could be repeated), fail */
+
+ if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
+
+ /* Continue as from after the group, updating the offsets high water
+ mark, since extracts may have been taken. */
+
+ do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
+
+ offset_top = md->end_offset_top;
+ eptr = md->end_match_ptr;
+
+ /* For a non-repeating ket, just continue at this level. This also
+ happens for a repeating ket if no characters were matched in the group.
+ This is the forcible breaking of infinite loops as implemented in Perl
+ 5.005. */
+
+ if (*ecode == OP_KET || eptr == saved_eptr)
+ {
+ ecode += 1+LINK_SIZE;
+ break;
+ }
+
+ /* The repeating kets try the rest of the pattern or restart from the
+ preceding bracket, in the appropriate order. The second "call" of match()
+ uses tail recursion, to avoid using another stack frame. */
+
+ if (*ecode == OP_KETRMIN)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM65);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode = prev;
+ goto TAIL_RECURSE;
+ }
+ else /* OP_KETRMAX */
+ {
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += 1 + LINK_SIZE;
+ goto TAIL_RECURSE;
+ }
+ /* Control never gets here */
+
+ /* Handle a capturing bracket, other than those that are possessive with an
+ unlimited repeat. If there is space in the offset vector, save the current
+ subject position in the working slot at the top of the vector. We mustn't
+ change the current values of the data slot, because they may be set from a
+ previous iteration of this group, and be referred to by a reference inside
+ the group. A failure to match might occur after the group has succeeded,
+ if something later on doesn't match. For this reason, we need to restore
+ the working value and also the values of the final offsets, in case they
+ were set by a previous iteration of the same bracket.
If there isn't enough space in the offset vector, treat this as if it were
a non-capturing bracket. Don't worry about setting the flag for the error
@@ -813,32 +945,55 @@
save_offset2 = md->offset_vector[offset+1];
save_offset3 = md->offset_vector[md->offset_end - number];
save_capture_last = md->capture_last;
+ save_mark = md->mark;
DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
md->offset_vector[md->offset_end - number] =
(int)(eptr - md->start_subject);
- flags = (op == OP_SCBRA)? match_cbegroup : 0;
- do
+ for (;;)
{
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags, RM1);
- if (rrc != MATCH_NOMATCH &&
- (rrc != MATCH_THEN || md->start_match_ptr != ecode))
- RRETURN(rrc);
+ if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM1);
+ if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */
+
+ /* If we backed up to a THEN, check whether it is within the current
+ branch by comparing the address of the THEN that is passed back with
+ the end of the branch. If it is within the current branch, and the
+ branch is one of two or more alternatives (it either starts or ends
+ with OP_ALT), we have reached the limit of THEN's action, so convert
+ the return code to NOMATCH, which will cause normal backtracking to
+ happen from now on. Otherwise, THEN is passed back to an outer
+ alternative. This implements Perl's treatment of parenthesized groups,
+ where a group not containing | does not affect the current alternative,
+ that is, (X) is NOT the same as (X|(*F)). */
+
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ /* Anything other than NOMATCH is passed back. */
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
md->capture_last = save_capture_last;
ecode += GET(ecode, 1);
+ md->mark = save_mark;
+ if (*ecode != OP_ALT) break;
}
- while (*ecode == OP_ALT);
DPRINTF(("bracket %d failed\n", number));
-
md->offset_vector[offset] = save_offset1;
md->offset_vector[offset+1] = save_offset2;
md->offset_vector[md->offset_end - number] = save_offset3;
- if (rrc != MATCH_THEN) md->mark = markptr;
- RRETURN(MATCH_NOMATCH);
+ /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */
+
+ RRETURN(rrc);
}
/* FALL THROUGH ... Insufficient room for saving captured contents. Treat
@@ -852,69 +1007,266 @@
/* VVVVVVVVVVVVVVVVVVVVVVVVV */
/* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* Non-capturing bracket. Loop for all the alternatives. When we get to the
- final alternative within the brackets, we would return the result of a
- recursive call to match() whatever happened. We can reduce stack usage by
- turning this into a tail recursion, except in the case when match_cbegroup
- is set.*/
+ /* Non-capturing or atomic group, except for possessive with unlimited
+ repeat and ONCE group with no captures. Loop for all the alternatives.
+
+ When we get to the final alternative within the brackets, we used to return
+ the result of a recursive call to match() whatever happened so it was
+ possible to reduce stack usage by turning this into a tail recursion,
+ except in the case of a possibly empty group. However, now that there is
+ the possiblity of (*THEN) occurring in the final alternative, this
+ optimization is no longer always possible.
+
+ We can optimize if we know there are no (*THEN)s in the pattern; at present
+ this is the best that can be done.
+
+ MATCH_ONCE is returned when the end of an atomic group is successfully
+ reached, but subsequent matching fails. It passes back up the tree (causing
+ captured values to be reset) until the original atomic group level is
+ reached. This is tested by comparing md->once_target with the start of the
+ group. At this point, the return is converted into MATCH_NOMATCH so that
+ previous backup points can be taken. */
+ case OP_ONCE:
case OP_BRA:
case OP_SBRA:
DPRINTF(("start non-capturing bracket\n"));
- flags = (op >= OP_SBRA)? match_cbegroup : 0;
+
for (;;)
{
- if (ecode[GET(ecode, 1)] != OP_ALT) /* Final alternative */
+ if (op >= OP_SBRA || op == OP_ONCE)
+ md->match_function_type = MATCH_CBEGROUP;
+
+ /* If this is not a possibly empty group, and there are no (*THEN)s in
+ the pattern, and this is the final alternative, optimize as described
+ above. */
+
+ else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
+ {
+ ecode += PRIV(OP_lengths)[*ecode];
+ goto TAIL_RECURSE;
+ }
+
+ /* In all other cases, we have to make another call to match(). */
+
+ save_mark = md->mark;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
+ RM2);
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
{
- if (flags == 0) /* Not a possibly empty group */
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH)
+ {
+ if (rrc == MATCH_ONCE)
{
- ecode += _pcre_OP_lengths[*ecode];
- DPRINTF(("bracket 0 tail recursion\n"));
- goto TAIL_RECURSE;
+ const pcre_uchar *scode = ecode;
+ if (*scode != OP_ONCE) /* If not at start, find it */
+ {
+ while (*scode == OP_ALT) scode += GET(scode, 1);
+ scode -= GET(scode, 1);
+ }
+ if (md->once_target == scode) rrc = MATCH_NOMATCH;
}
+ RRETURN(rrc);
+ }
+ ecode += GET(ecode, 1);
+ md->mark = save_mark;
+ if (*ecode != OP_ALT) break;
+ }
- /* Possibly empty group; can't use tail recursion. */
+ RRETURN(MATCH_NOMATCH);
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
- eptrb, flags, RM48);
- if (rrc == MATCH_NOMATCH) md->mark = markptr;
- RRETURN(rrc);
+ /* Handle possessive capturing brackets with an unlimited repeat. We come
+ here from BRAZERO with allow_zero set TRUE. The offset_vector values are
+ handled similarly to the normal case above. However, the matching is
+ different. The end of these brackets will always be OP_KETRPOS, which
+ returns MATCH_KETRPOS without going further in the pattern. By this means
+ we can handle the group by iteration rather than recursion, thereby
+ reducing the amount of stack needed. */
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ allow_zero = FALSE;
+
+ POSSESSIVE_CAPTURE:
+ number = GET2(ecode, 1+LINK_SIZE);
+ offset = number << 1;
+
+#ifdef PCRE_DEBUG
+ printf("start possessive bracket %d\n", number);
+ printf("subject=");
+ pchars(eptr, 16, TRUE, md);
+ printf("\n");
+#endif
+
+ if (offset < md->offset_max)
+ {
+ matched_once = FALSE;
+ code_offset = (int)(ecode - md->start_code);
+
+ save_offset1 = md->offset_vector[offset];
+ save_offset2 = md->offset_vector[offset+1];
+ save_offset3 = md->offset_vector[md->offset_end - number];
+ save_capture_last = md->capture_last;
+
+ DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
+
+ /* Each time round the loop, save the current subject position for use
+ when the group matches. For MATCH_MATCH, the group has matched, so we
+ restart it with a new subject starting position, remembering that we had
+ at least one match. For MATCH_NOMATCH, carry on with the alternatives, as
+ usual. If we haven't matched any alternatives in any iteration, check to
+ see if a previous iteration matched. If so, the group has matched;
+ continue from afterwards. Otherwise it has failed; restore the previous
+ capture values before returning NOMATCH. */
+
+ for (;;)
+ {
+ md->offset_vector[md->offset_end - number] =
+ (int)(eptr - md->start_subject);
+ if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM63);
+ if (rrc == MATCH_KETRPOS)
+ {
+ offset_top = md->end_offset_top;
+ eptr = md->end_match_ptr;
+ ecode = md->start_code + code_offset;
+ save_capture_last = md->capture_last;
+ matched_once = TRUE;
+ continue;
+ }
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->capture_last = save_capture_last;
+ ecode += GET(ecode, 1);
+ if (*ecode != OP_ALT) break;
+ }
+
+ if (!matched_once)
+ {
+ md->offset_vector[offset] = save_offset1;
+ md->offset_vector[offset+1] = save_offset2;
+ md->offset_vector[md->offset_end - number] = save_offset3;
}
- /* For non-final alternatives, continue the loop for a NOMATCH result;
- otherwise return. */
+ if (allow_zero || matched_once)
+ {
+ ecode += 1 + LINK_SIZE;
+ break;
+ }
- RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
- eptrb, flags, RM2);
- if (rrc != MATCH_NOMATCH &&
- (rrc != MATCH_THEN || md->start_match_ptr != ecode))
- RRETURN(rrc);
+ RRETURN(MATCH_NOMATCH);
+ }
+
+ /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
+ as a non-capturing bracket. */
+
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+ DPRINTF(("insufficient capture room: treat as non-capturing\n"));
+
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+ /* Non-capturing possessive bracket with unlimited repeat. We come here
+ from BRAZERO with allow_zero = TRUE. The code is similar to the above,
+ without the capturing complication. It is written out separately for speed
+ and cleanliness. */
+
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ allow_zero = FALSE;
+
+ POSSESSIVE_NON_CAPTURE:
+ matched_once = FALSE;
+ code_offset = (int)(ecode - md->start_code);
+
+ for (;;)
+ {
+ if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM48);
+ if (rrc == MATCH_KETRPOS)
+ {
+ offset_top = md->end_offset_top;
+ eptr = md->end_match_ptr;
+ ecode = md->start_code + code_offset;
+ matched_once = TRUE;
+ continue;
+ }
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode, 1);
+ if (*ecode != OP_ALT) break;
}
+
+ if (matched_once || allow_zero)
+ {
+ ecode += 1 + LINK_SIZE;
+ break;
+ }
+ RRETURN(MATCH_NOMATCH);
+
/* Control never reaches here. */
/* Conditional group: compilation checked that there are no more than
two branches. If the condition is false, skipping the first branch takes us
past the end if there is only one branch, but that's OK because that is
- exactly what going to the ket would do. As there is only one branch to be
- obeyed, we can use tail recursion to avoid using another stack frame. */
+ exactly what going to the ket would do. */
case OP_COND:
case OP_SCOND:
- codelink= GET(ecode, 1);
+ codelink = GET(ecode, 1);
/* Because of the way auto-callout works during compile, a callout item is
inserted between OP_COND and an assertion condition. */
if (ecode[LINK_SIZE+1] == OP_CALLOUT)
{
- if (pcre_callout != NULL)
+ if (PUBL(callout) != NULL)
{
- pcre_callout_block cb;
- cb.version = 1; /* Version 1 of the callout block */
+ PUBL(callout_block) cb;
+ cb.version = 2; /* Version 1 of the callout block */
cb.callout_number = ecode[LINK_SIZE+2];
cb.offset_vector = md->offset_vector;
+#ifdef COMPILE_PCRE8
cb.subject = (PCRE_SPTR)md->start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)md->start_subject;
+#endif
cb.subject_length = (int)(md->end_subject - md->start_subject);
cb.start_match = (int)(mstart - md->start_subject);
cb.current_position = (int)(eptr - md->start_subject);
@@ -923,10 +1275,11 @@
cb.capture_top = offset_top/2;
cb.capture_last = md->capture_last;
cb.callout_data = md->callout_data;
- if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
+ cb.mark = md->nomatch_mark;
+ if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
if (rrc < 0) RRETURN(rrc);
}
- ecode += _pcre_OP_lengths[OP_CALLOUT];
+ ecode += PRIV(OP_lengths)[OP_CALLOUT];
}
condcode = ecode[LINK_SIZE+1];
@@ -943,16 +1296,16 @@
else
{
int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/
- condition = (recno == RREF_ANY || recno == md->recursive->group_num);
+ condition = (recno == RREF_ANY || recno == md->recursive->group_num);
/* If the test is for recursion into a specific subpattern, and it is
false, but the test was set up by name, scan the table to see if the
name refers to any other numbers, and test them. The condition is true
if any one is set. */
- if (!condition && condcode == OP_NRREF && recno != RREF_ANY)
+ if (!condition && condcode == OP_NRREF)
{
- uschar *slotA = md->name_table;
+ pcre_uchar *slotA = md->name_table;
for (i = 0; i < md->name_count; i++)
{
if (GET2(slotA, 0) == recno) break;
@@ -965,11 +1318,11 @@
if (i < md->name_count)
{
- uschar *slotB = slotA;
+ pcre_uchar *slotB = slotA;
while (slotB > md->name_table)
{
slotB -= md->name_entry_size;
- if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
{
condition = GET2(slotB, 0) == md->recursive->group_num;
if (condition) break;
@@ -985,7 +1338,7 @@
for (i++; i < md->name_count; i++)
{
slotB += md->name_entry_size;
- if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
{
condition = GET2(slotB, 0) == md->recursive->group_num;
if (condition) break;
@@ -998,7 +1351,7 @@
/* Chose branch according to the condition */
- ecode += condition? 3 : GET(ecode, 1);
+ ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
}
}
@@ -1015,7 +1368,7 @@
if (!condition && condcode == OP_NCREF)
{
int refno = offset >> 1;
- uschar *slotA = md->name_table;
+ pcre_uchar *slotA = md->name_table;
for (i = 0; i < md->name_count; i++)
{
@@ -1029,11 +1382,11 @@
if (i < md->name_count)
{
- uschar *slotB = slotA;
+ pcre_uchar *slotB = slotA;
while (slotB > md->name_table)
{
slotB -= md->name_entry_size;
- if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
{
offset = GET2(slotB, 0) << 1;
condition = offset < offset_top &&
@@ -1051,7 +1404,7 @@
for (i++; i < md->name_count; i++)
{
slotB += md->name_entry_size;
- if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
{
offset = GET2(slotB, 0) << 1;
condition = offset < offset_top &&
@@ -1066,7 +1419,7 @@
/* Chose branch according to the condition */
- ecode += condition? 3 : GET(ecode, 1);
+ ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
}
else if (condcode == OP_DEF) /* DEFINE - always false */
@@ -1076,21 +1429,26 @@
}
/* The condition is an assertion. Call match() to evaluate it - setting
- the final argument match_condassert causes it to stop at the end of an
- assertion. */
+ md->match_function_type to MATCH_CONDASSERT causes it to stop at the end of
+ an assertion. */
else
{
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
- match_condassert, RM3);
+ md->match_function_type = MATCH_CONDASSERT;
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM3);
if (rrc == MATCH_MATCH)
{
+ if (md->end_offset_top > offset_top)
+ offset_top = md->end_offset_top; /* Captures may have happened */
condition = TRUE;
ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
while (*ecode == OP_ALT) ecode += GET(ecode, 1);
}
- else if (rrc != MATCH_NOMATCH &&
- (rrc != MATCH_THEN || md->start_match_ptr != ecode))
+
+ /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
+ assertion; it is therefore treated as NOMATCH. */
+
+ else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
{
RRETURN(rrc); /* Need braces because of following else */
}
@@ -1101,26 +1459,32 @@
}
}
- /* We are now at the branch that is to be obeyed. As there is only one,
- we can use tail recursion to avoid using another stack frame, except when
- match_cbegroup is required for an unlimited repeat of a possibly empty
- group. If the second alternative doesn't exist, we can just plough on. */
+ /* We are now at the branch that is to be obeyed. As there is only one, can
+ use tail recursion to avoid using another stack frame, except when there is
+ unlimited repeat of a possibly empty group. In the latter case, a recursive
+ call to match() is always required, unless the second alternative doesn't
+ exist, in which case we can just plough on. Note that, for compatibility
+ with Perl, the | in a conditional group is NOT treated as creating two
+ alternatives. If a THEN is encountered in the branch, it propagates out to
+ the enclosing alternative (unless nested in a deeper set of alternatives,
+ of course). */
if (condition || *ecode == OP_ALT)
{
- ecode += 1 + LINK_SIZE;
- if (op == OP_SCOND) /* Possibly empty group */
+ if (op != OP_SCOND)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49);
- RRETURN(rrc);
- }
- else /* Group must match something */
- {
- flags = 0;
+ ecode += 1 + LINK_SIZE;
goto TAIL_RECURSE;
}
+
+ md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);
+ RRETURN(rrc);
}
- else /* Condition false & no alternative */
+
+ /* Condition false & no alternative; continue after the group. */
+
+ else
{
ecode += 1 + LINK_SIZE;
}
@@ -1147,39 +1511,27 @@
md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
if (offset_top <= offset) offset_top = offset + 2;
}
- ecode += 3;
+ ecode += 1 + IMM2_SIZE;
break;
- /* End of the pattern, either real or forced. If we are in a top-level
- recursion, we should restore the offsets appropriately and continue from
- after the call. */
+ /* End of the pattern, either real or forced. */
- case OP_ACCEPT:
case OP_END:
- if (md->recursive != NULL && md->recursive->group_num == 0)
- {
- recursion_info *rec = md->recursive;
- DPRINTF(("End of pattern in a (?0) recursion\n"));
- md->recursive = rec->prevrec;
- memmove(md->offset_vector, rec->offset_save,
- rec->saved_max * sizeof(int));
- offset_top = rec->save_offset_top;
- ims = original_ims;
- ecode = rec->after_call;
- break;
- }
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
- /* Otherwise, if we have matched an empty string, fail if PCRE_NOTEMPTY is
- set, or if PCRE_NOTEMPTY_ATSTART is set and we have matched at the start of
- the subject. In both cases, backtracking will then try other alternatives,
- if any. */
-
- if (eptr == mstart &&
- (md->notempty ||
- (md->notempty_atstart &&
- mstart == md->start_subject + md->start_offset)))
- MRRETURN(MATCH_NOMATCH);
+ /* If we have matched an empty string, fail if not in an assertion and not
+ in a recursion if either PCRE_NOTEMPTY is set, or if PCRE_NOTEMPTY_ATSTART
+ is set and we have matched at the start of the subject. In both cases,
+ backtracking will then try other alternatives, if any. */
+
+ if (eptr == mstart && op != OP_ASSERT_ACCEPT &&
+ md->recursive == NULL &&
+ (md->notempty ||
+ (md->notempty_atstart &&
+ mstart == md->start_subject + md->start_offset)))
+ RRETURN(MATCH_NOMATCH);
/* Otherwise, we have a match. */
@@ -1188,47 +1540,60 @@
md->start_match_ptr = mstart; /* and the start (\K can modify) */
/* For some reason, the macros don't work properly if an expression is
- given as the argument to MRRETURN when the heap is in use. */
+ given as the argument to RRETURN when the heap is in use. */
rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
- MRRETURN(rrc);
-
- /* Change option settings */
-
- case OP_OPT:
- ims = ecode[1];
- ecode += 2;
- DPRINTF(("ims set to %02lx\n", ims));
- break;
+ RRETURN(rrc);
/* Assertion brackets. Check the alternative branches in turn - the
matching won't pass the KET for an assertion. If any one branch matches,
the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
start of each branch to move the current point backwards, so the code at
- this level is identical to the lookahead case. */
+ this level is identical to the lookahead case. When the assertion is part
+ of a condition, we want to return immediately afterwards. The caller of
+ this incarnation of the match() function will have set MATCH_CONDASSERT in
+ md->match_function type, and one of these opcodes will be the first opcode
+ that is processed. We use a local variable that is preserved over calls to
+ match() to remember this case. */
case OP_ASSERT:
case OP_ASSERTBACK:
+ save_mark = md->mark;
+ if (md->match_function_type == MATCH_CONDASSERT)
+ {
+ condassert = TRUE;
+ md->match_function_type = 0;
+ }
+ else condassert = FALSE;
+
do
{
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
- RM4);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4);
if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
{
mstart = md->start_match_ptr; /* In case \K reset it */
break;
}
- if (rrc != MATCH_NOMATCH &&
- (rrc != MATCH_THEN || md->start_match_ptr != ecode))
- RRETURN(rrc);
+ md->mark = save_mark;
+
+ /* A COMMIT failure must fail the entire assertion, without trying any
+ subsequent branches. */
+
+ if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);
+
+ /* PCRE does not allow THEN to escape beyond an assertion; it
+ is treated as NOMATCH. */
+
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
ecode += GET(ecode, 1);
}
while (*ecode == OP_ALT);
- if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH);
+
+ if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
/* If checking an assertion for a condition, return MATCH_MATCH. */
- if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH);
+ if (condassert) RRETURN(MATCH_MATCH);
/* Continue from after the assertion, updating the offsets high water
mark, since extracts may have been taken during the assertion. */
@@ -1244,24 +1609,34 @@
case OP_ASSERT_NOT:
case OP_ASSERTBACK_NOT:
+ save_mark = md->mark;
+ if (md->match_function_type == MATCH_CONDASSERT)
+ {
+ condassert = TRUE;
+ md->match_function_type = 0;
+ }
+ else condassert = FALSE;
+
do
{
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
- RM5);
- if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
+ md->mark = save_mark;
+ if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
{
do ecode += GET(ecode,1); while (*ecode == OP_ALT);
break;
}
- if (rrc != MATCH_NOMATCH &&
- (rrc != MATCH_THEN || md->start_match_ptr != ecode))
- RRETURN(rrc);
+
+ /* PCRE does not allow THEN to escape beyond an assertion; it is treated
+ as NOMATCH. */
+
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
ecode += GET(ecode,1);
}
while (*ecode == OP_ALT);
- if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH);
+ if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */
ecode += 1 + LINK_SIZE;
continue;
@@ -1272,14 +1647,14 @@
back a number of characters, not bytes. */
case OP_REVERSE:
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
i = GET(ecode, 1);
while (i-- > 0)
{
eptr--;
- if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
+ if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
BACKCHAR(eptr);
}
}
@@ -1290,7 +1665,7 @@
{
eptr -= GET(ecode, 1);
- if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
+ if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
}
/* Save the earliest consulted character, then skip to next op code */
@@ -1304,13 +1679,17 @@
function is able to force a failure. */
case OP_CALLOUT:
- if (pcre_callout != NULL)
+ if (PUBL(callout) != NULL)
{
- pcre_callout_block cb;
- cb.version = 1; /* Version 1 of the callout block */
+ PUBL(callout_block) cb;
+ cb.version = 2; /* Version 1 of the callout block */
cb.callout_number = ecode[1];
cb.offset_vector = md->offset_vector;
+#ifdef COMPILE_PCRE8
cb.subject = (PCRE_SPTR)md->start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)md->start_subject;
+#endif
cb.subject_length = (int)(md->end_subject - md->start_subject);
cb.start_match = (int)(mstart - md->start_subject);
cb.current_position = (int)(eptr - md->start_subject);
@@ -1319,7 +1698,8 @@
cb.capture_top = offset_top/2;
cb.capture_last = md->capture_last;
cb.callout_data = md->callout_data;
- if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
+ cb.mark = md->nomatch_mark;
+ if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
if (rrc < 0) RRETURN(rrc);
}
ecode += 2 + 2*LINK_SIZE;
@@ -1329,38 +1709,48 @@
offset data is the offset to the starting bracket from the start of the
whole pattern. (This is so that it works from duplicated subpatterns.)
- If there are any capturing brackets started but not finished, we have to
- save their starting points and reinstate them after the recursion. However,
- we don't know how many such there are (offset_top records the completed
- total) so we just have to save all the potential data. There may be up to
- 65535 such values, which is too large to put on the stack, but using malloc
- for small numbers seems expensive. As a compromise, the stack is used when
- there are no more than REC_STACK_SAVE_MAX values to store; otherwise malloc
- is used. A problem is what to do if the malloc fails ... there is no way of
- returning to the top level with an error. Save the top REC_STACK_SAVE_MAX
- values on the stack, and accept that the rest may be wrong.
+ The state of the capturing groups is preserved over recursion, and
+ re-instated afterwards. We don't know how many are started and not yet
+ finished (offset_top records the completed total) so we just have to save
+ all the potential data. There may be up to 65535 such values, which is too
+ large to put on the stack, but using malloc for small numbers seems
+ expensive. As a compromise, the stack is used when there are no more than
+ REC_STACK_SAVE_MAX values to store; otherwise malloc is used.
There are also other values that have to be saved. We use a chained
sequence of blocks that actually live on the stack. Thanks to Robin Houston
- for the original version of this logic. */
+ for the original version of this logic. It has, however, been hacked around
+ a lot, so he is not to blame for the current way it works. */
case OP_RECURSE:
{
+ recursion_info *ri;
+ int recno;
+
callpat = md->start_code + GET(ecode, 1);
- new_recursive.group_num = (callpat == md->start_code)? 0 :
+ recno = (callpat == md->start_code)? 0 :
GET2(callpat, 1 + LINK_SIZE);
+ /* Check for repeating a recursion without advancing the subject pointer.
+ This should catch convoluted mutual recursions. (Some simple cases are
+ caught at compile time.) */
+
+ for (ri = md->recursive; ri != NULL; ri = ri->prevrec)
+ if (recno == ri->group_num && eptr == ri->subject_position)
+ RRETURN(PCRE_ERROR_RECURSELOOP);
+
/* Add to "recursing stack" */
+ new_recursive.group_num = recno;
+ new_recursive.subject_position = eptr;
new_recursive.prevrec = md->recursive;
md->recursive = &new_recursive;
- /* Find where to continue from afterwards */
+ /* Where to continue from afterwards */
ecode += 1 + LINK_SIZE;
- new_recursive.after_call = ecode;
- /* Now save the offset data. */
+ /* Now save the offset data */
new_recursive.saved_max = md->offset_end;
if (new_recursive.saved_max <= REC_STACK_SAVE_MAX)
@@ -1368,43 +1758,54 @@
else
{
new_recursive.offset_save =
- (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));
+ (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
}
-
memcpy(new_recursive.offset_save, md->offset_vector,
new_recursive.saved_max * sizeof(int));
- new_recursive.save_offset_top = offset_top;
- /* OK, now we can do the recursion. For each top-level alternative we
- restore the offset and recursion data. */
+ /* OK, now we can do the recursion. After processing each alternative,
+ restore the offset data. If there were nested recursions, md->recursive
+ might be changed, so reset it before looping. */
DPRINTF(("Recursing into group %d\n", new_recursive.group_num));
- flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;
+ cbegroup = (*callpat >= OP_SBRA);
do
{
- RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
- md, ims, eptrb, flags, RM6);
+ if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
+ md, eptrb, RM6);
+ memcpy(md->offset_vector, new_recursive.offset_save,
+ new_recursive.saved_max * sizeof(int));
+ md->recursive = new_recursive.prevrec;
if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
{
DPRINTF(("Recursion matched\n"));
- md->recursive = new_recursive.prevrec;
if (new_recursive.offset_save != stacksave)
- (pcre_free)(new_recursive.offset_save);
- MRRETURN(MATCH_MATCH);
+ (PUBL(free))(new_recursive.offset_save);
+
+ /* Set where we got to in the subject, and reset the start in case
+ it was changed by \K. This *is* propagated back out of a recursion,
+ for Perl compatibility. */
+
+ eptr = md->end_match_ptr;
+ mstart = md->start_match_ptr;
+ goto RECURSION_MATCHED; /* Exit loop; end processing */
}
- else if (rrc != MATCH_NOMATCH &&
- (rrc != MATCH_THEN || md->start_match_ptr != ecode))
+
+ /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it
+ is treated as NOMATCH. */
+
+ else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
+ rrc != MATCH_COMMIT)
{
DPRINTF(("Recursion gave error %d\n", rrc));
if (new_recursive.offset_save != stacksave)
- (pcre_free)(new_recursive.offset_save);
+ (PUBL(free))(new_recursive.offset_save);
RRETURN(rrc);
}
md->recursive = &new_recursive;
- memcpy(md->offset_vector, new_recursive.offset_save,
- new_recursive.saved_max * sizeof(int));
callpat += GET(callpat, 1);
}
while (*callpat == OP_ALT);
@@ -1412,91 +1813,12 @@
DPRINTF(("Recursion didn't match\n"));
md->recursive = new_recursive.prevrec;
if (new_recursive.offset_save != stacksave)
- (pcre_free)(new_recursive.offset_save);
- MRRETURN(MATCH_NOMATCH);
- }
- /* Control never reaches here */
-
- /* "Once" brackets are like assertion brackets except that after a match,
- the point in the subject string is not moved back. Thus there can never be
- a move back into the brackets. Friedl calls these "atomic" subpatterns.
- Check the alternative branches in turn - the matching won't pass the KET
- for this kind of subpattern. If any one branch matches, we carry on as at
- the end of a normal bracket, leaving the subject pointer, but resetting
- the start-of-match value in case it was changed by \K. */
-
- case OP_ONCE:
- prev = ecode;
- saved_eptr = eptr;
-
- do
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
- if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */
- {
- mstart = md->start_match_ptr;
- break;
- }
- if (rrc != MATCH_NOMATCH &&
- (rrc != MATCH_THEN || md->start_match_ptr != ecode))
- RRETURN(rrc);
- ecode += GET(ecode,1);
- }
- while (*ecode == OP_ALT);
-
- /* If hit the end of the group (which could be repeated), fail */
-
- if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
-
- /* Continue as from after the assertion, updating the offsets high water
- mark, since extracts may have been taken. */
-
- do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
-
- offset_top = md->end_offset_top;
- eptr = md->end_match_ptr;
-
- /* For a non-repeating ket, just continue at this level. This also
- happens for a repeating ket if no characters were matched in the group.
- This is the forcible breaking of infinite loops as implemented in Perl
- 5.005. If there is an options reset, it will get obeyed in the normal
- course of events. */
-
- if (*ecode == OP_KET || eptr == saved_eptr)
- {
- ecode += 1+LINK_SIZE;
- break;
- }
-
- /* The repeating kets try the rest of the pattern or restart from the
- preceding bracket, in the appropriate order. The second "call" of match()
- uses tail recursion, to avoid using another stack frame. We need to reset
- any options that changed within the bracket before re-running it, so
- check the next opcode. */
-
- if (ecode[1+LINK_SIZE] == OP_OPT)
- {
- ims = (ims & ~PCRE_IMS) | ecode[4];
- DPRINTF(("ims set to %02lx at group repeat\n", ims));
+ (PUBL(free))(new_recursive.offset_save);
+ RRETURN(MATCH_NOMATCH);
}
- if (*ecode == OP_KETRMIN)
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode = prev;
- flags = 0;
- goto TAIL_RECURSE;
- }
- else /* OP_KETRMAX */
- {
- RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode += 1 + LINK_SIZE;
- flags = 0;
- goto TAIL_RECURSE;
- }
- /* Control never gets here */
+ RECURSION_MATCHED:
+ break;
/* An alternation is the end of a branch; scan along to find the end of the
bracketed group and go to there. */
@@ -1512,140 +1834,181 @@
optional ones preceded by BRAZERO or BRAMINZERO. */
case OP_BRAZERO:
- {
- next = ecode+1;
- RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- do next += GET(next,1); while (*next == OP_ALT);
- ecode = next + 1 + LINK_SIZE;
- }
+ next = ecode + 1;
+ RMATCH(eptr, next, offset_top, md, eptrb, RM10);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ do next += GET(next, 1); while (*next == OP_ALT);
+ ecode = next + 1 + LINK_SIZE;
break;
case OP_BRAMINZERO:
- {
- next = ecode+1;
- do next += GET(next, 1); while (*next == OP_ALT);
- RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode++;
- }
+ next = ecode + 1;
+ do next += GET(next, 1); while (*next == OP_ALT);
+ RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, eptrb, RM11);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode++;
break;
case OP_SKIPZERO:
- {
- next = ecode+1;
- do next += GET(next,1); while (*next == OP_ALT);
- ecode = next + 1 + LINK_SIZE;
- }
+ next = ecode+1;
+ do next += GET(next,1); while (*next == OP_ALT);
+ ecode = next + 1 + LINK_SIZE;
break;
+ /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything
+ here; just jump to the group, with allow_zero set TRUE. */
+
+ case OP_BRAPOSZERO:
+ op = *(++ecode);
+ allow_zero = TRUE;
+ if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE;
+ goto POSSESSIVE_NON_CAPTURE;
+
/* End of a group, repeated or non-repeating. */
case OP_KET:
case OP_KETRMIN:
case OP_KETRMAX:
+ case OP_KETRPOS:
prev = ecode - GET(ecode, 1);
/* If this was a group that remembered the subject start, in order to break
infinite repeats of empty string matches, retrieve the subject start from
the chain. Otherwise, set it NULL. */
- if (*prev >= OP_SBRA)
+ if (*prev >= OP_SBRA || *prev == OP_ONCE)
{
saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */
eptrb = eptrb->epb_prev; /* Backup to previous group */
}
else saved_eptr = NULL;
- /* If we are at the end of an assertion group or an atomic group, stop
- matching and return MATCH_MATCH, but record the current high water mark for
- use by positive assertions. We also need to record the match start in case
- it was changed by \K. */
-
- if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
- *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
- *prev == OP_ONCE)
+ /* If we are at the end of an assertion group or a non-capturing atomic
+ group, stop matching and return MATCH_MATCH, but record the current high
+ water mark for use by positive assertions. We also need to record the match
+ start in case it was changed by \K. */
+
+ if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||
+ *prev == OP_ONCE_NC)
{
- md->end_match_ptr = eptr; /* For ONCE */
+ md->end_match_ptr = eptr; /* For ONCE_NC */
md->end_offset_top = offset_top;
md->start_match_ptr = mstart;
- MRRETURN(MATCH_MATCH);
+ RRETURN(MATCH_MATCH); /* Sets md->mark */
}
/* For capturing groups we have to check the group number back at the start
and if necessary complete handling an extraction by setting the offsets and
- bumping the high water mark. Note that whole-pattern recursion is coded as
- a recurse into group 0, so it won't be picked up here. Instead, we catch it
- when the OP_END is reached. Other recursion is handled here. */
+ bumping the high water mark. Whole-pattern recursion is coded as a recurse
+ into group 0, so it won't be picked up here. Instead, we catch it when the
+ OP_END is reached. Other recursion is handled here. We just have to record
+ the current subject position and start match pointer and give a MATCH
+ return. */
- if (*prev == OP_CBRA || *prev == OP_SCBRA)
+ if (*prev == OP_CBRA || *prev == OP_SCBRA ||
+ *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS)
{
number = GET2(prev, 1+LINK_SIZE);
offset = number << 1;
-#ifdef PCRE_DEBUG
- printf("end bracket %d", number);
- printf("\n");
-#endif
+#ifdef PCRE_DEBUG
+ printf("end bracket %d", number);
+ printf("\n");
+#endif
+
+ /* Handle a recursively called group. */
+
+ if (md->recursive != NULL && md->recursive->group_num == number)
+ {
+ md->end_match_ptr = eptr;
+ md->start_match_ptr = mstart;
+ RRETURN(MATCH_MATCH);
+ }
+
+ /* Deal with capturing */
md->capture_last = number;
if (offset >= md->offset_max) md->offset_overflow = TRUE; else
{
+ /* If offset is greater than offset_top, it means that we are
+ "skipping" a capturing group, and that group's offsets must be marked
+ unset. In earlier versions of PCRE, all the offsets were unset at the
+ start of matching, but this doesn't work because atomic groups and
+ assertions can cause a value to be set that should later be unset.
+ Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as
+ part of the atomic group, but this is not on the final matching path,
+ so must be unset when 2 is set. (If there is no group 2, there is no
+ problem, because offset_top will then be 2, indicating no capture.) */
+
+ if (offset > offset_top)
+ {
+ register int *iptr = md->offset_vector + offset_top;
+ register int *iend = md->offset_vector + offset;
+ while (iptr < iend) *iptr++ = -1;
+ }
+
+ /* Now make the extraction */
+
md->offset_vector[offset] =
md->offset_vector[md->offset_end - number];
md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
if (offset_top <= offset) offset_top = offset + 2;
}
+ }
- /* Handle a recursively called group. Restore the offsets
- appropriately and continue from after the call. */
+ /* For an ordinary non-repeating ket, just continue at this level. This
+ also happens for a repeating ket if no characters were matched in the
+ group. This is the forcible breaking of infinite loops as implemented in
+ Perl 5.005. For a non-repeating atomic group that includes captures,
+ establish a backup point by processing the rest of the pattern at a lower
+ level. If this results in a NOMATCH return, pass MATCH_ONCE back to the
+ original OP_ONCE level, thereby bypassing intermediate backup points, but
+ resetting any captures that happened along the way. */
- if (md->recursive != NULL && md->recursive->group_num == number)
+ if (*ecode == OP_KET || eptr == saved_eptr)
+ {
+ if (*prev == OP_ONCE)
{
- recursion_info *rec = md->recursive;
- DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
- md->recursive = rec->prevrec;
- memcpy(md->offset_vector, rec->offset_save,
- rec->saved_max * sizeof(int));
- offset_top = rec->save_offset_top;
- ecode = rec->after_call;
- ims = original_ims;
- break;
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM12);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
+ RRETURN(MATCH_ONCE);
}
+ ecode += 1 + LINK_SIZE; /* Carry on at this level */
+ break;
}
- /* For both capturing and non-capturing groups, reset the value of the ims
- flags, in case they got changed during the group. */
-
- ims = original_ims;
- DPRINTF(("ims reset to %02lx\n", ims));
-
- /* For a non-repeating ket, just continue at this level. This also
- happens for a repeating ket if no characters were matched in the group.
- This is the forcible breaking of infinite loops as implemented in Perl
- 5.005. If there is an options reset, it will get obeyed in the normal
- course of events. */
+ /* OP_KETRPOS is a possessive repeating ket. Remember the current position,
+ and return the MATCH_KETRPOS. This makes it possible to do the repeats one
+ at a time from the outer level, thus saving stack. */
- if (*ecode == OP_KET || eptr == saved_eptr)
+ if (*ecode == OP_KETRPOS)
{
- ecode += 1 + LINK_SIZE;
- break;
+ md->end_match_ptr = eptr;
+ md->end_offset_top = offset_top;
+ RRETURN(MATCH_KETRPOS);
}
- /* The repeating kets try the rest of the pattern or restart from the
- preceding bracket, in the appropriate order. In the second case, we can use
- tail recursion to avoid using another stack frame, unless we have an
- unlimited repeat of a group that can match an empty string. */
-
- flags = (*prev >= OP_SBRA)? match_cbegroup : 0;
+ /* The normal repeating kets try the rest of the pattern or restart from
+ the preceding bracket, in the appropriate order. In the second case, we can
+ use tail recursion to avoid using another stack frame, unless we have an
+ an atomic group or an unlimited repeat of a group that can match an empty
+ string. */
if (*ecode == OP_KETRMIN)
{
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM7);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (flags != 0) /* Could match an empty string */
+ if (*prev == OP_ONCE)
+ {
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM8);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
+ RRETURN(MATCH_ONCE);
+ }
+ if (*prev >= OP_SBRA) /* Could match an empty string */
{
- RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50);
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM50);
RRETURN(rrc);
}
ecode = prev;
@@ -1653,39 +2016,47 @@
}
else /* OP_KETRMAX */
{
- RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM13);
+ if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (*prev == OP_ONCE)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM9);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->once_target = prev;
+ RRETURN(MATCH_ONCE);
+ }
ecode += 1 + LINK_SIZE;
- flags = 0;
goto TAIL_RECURSE;
}
/* Control never gets here */
- /* Start of subject unless notbol, or after internal newline if multiline */
+ /* Not multiline mode: start of subject assertion, unless notbol. */
case OP_CIRC:
- if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);
- if ((ims & PCRE_MULTILINE) != 0)
- {
- if (eptr != md->start_subject &&
- (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
- MRRETURN(MATCH_NOMATCH);
- ecode++;
- break;
- }
- /* ... else fall through */
+ if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
/* Start of subject assertion */
case OP_SOD:
- if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH);
+ if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ /* Multiline mode: start of subject unless notbol, or after any newline. */
+
+ case OP_CIRCM:
+ if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
+ if (eptr != md->start_subject &&
+ (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
+ RRETURN(MATCH_NOMATCH);
ecode++;
break;
/* Start of match assertion */
case OP_SOM:
- if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH);
+ if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
ecode++;
break;
@@ -1696,34 +2067,47 @@
ecode++;
break;
- /* Assert before internal newline if multiline, or before a terminating
- newline unless endonly is set, else end of subject unless noteol is set. */
+ /* Multiline mode: assert before any newline, or before end of subject
+ unless noteol is set. */
- case OP_DOLL:
- if ((ims & PCRE_MULTILINE) != 0)
+ case OP_DOLLM:
+ if (eptr < md->end_subject)
{
- if (eptr < md->end_subject)
- { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }
- else
+ if (!IS_NEWLINE(eptr))
{
- if (md->noteol) MRRETURN(MATCH_NOMATCH);
- SCHECK_PARTIAL();
+ if (md->partial != 0 &&
+ eptr + 1 >= md->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ *eptr == NLBLOCK->nl[0])
+ {
+ md->hitend = TRUE;
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
+ }
+ RRETURN(MATCH_NOMATCH);
}
- ecode++;
- break;
}
- else /* Not multiline */
+ else
{
- if (md->noteol) MRRETURN(MATCH_NOMATCH);
- if (!md->endonly) goto ASSERT_NL_OR_EOS;
+ if (md->noteol) RRETURN(MATCH_NOMATCH);
+ SCHECK_PARTIAL();
}
+ ecode++;
+ break;
+
+ /* Not multiline mode: assert before a terminating newline or before end of
+ subject unless noteol is set. */
+
+ case OP_DOLL:
+ if (md->noteol) RRETURN(MATCH_NOMATCH);
+ if (!md->endonly) goto ASSERT_NL_OR_EOS;
/* ... else fall through for endonly */
/* End of subject assertion (\z) */
case OP_EOD:
- if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);
+ if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
SCHECK_PARTIAL();
ecode++;
break;
@@ -1734,7 +2118,18 @@
ASSERT_NL_OR_EOS:
if (eptr < md->end_subject &&
(!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
- MRRETURN(MATCH_NOMATCH);
+ {
+ if (md->partial != 0 &&
+ eptr + 1 >= md->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ *eptr == NLBLOCK->nl[0])
+ {
+ md->hitend = TRUE;
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
/* Either at end of string or \n before end. */
@@ -1753,15 +2148,15 @@
be "non-word" characters. Remember the earliest consulted character for
partial matching. */
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
/* Get status of previous character */
if (eptr == md->start_subject) prev_is_word = FALSE; else
{
- USPTR lastptr = eptr - 1;
- while((*lastptr & 0xc0) == 0x80) lastptr--;
+ PCRE_PUCHAR lastptr = eptr - 1;
+ BACKCHAR(lastptr);
if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
GETCHAR(c, lastptr);
#ifdef SUPPORT_UCP
@@ -1826,7 +2221,8 @@
}
else
#endif
- prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);
+ prev_is_word = MAX_255(eptr[-1])
+ && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
}
/* Get status of next character */
@@ -1849,30 +2245,47 @@
}
else
#endif
- cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);
+ cur_is_word = MAX_255(*eptr)
+ && ((md->ctypes[*eptr] & ctype_word) != 0);
}
/* Now see if the situation is what we want */
if ((*ecode++ == OP_WORD_BOUNDARY)?
cur_is_word == prev_is_word : cur_is_word != prev_is_word)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
break;
- /* Match a single character type; inline for speed */
+ /* Match any single character type except newline; have to take care with
+ CRLF newlines and partial matching. */
case OP_ANY:
- if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ if (md->partial != 0 &&
+ eptr + 1 >= md->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ *eptr == NLBLOCK->nl[0])
+ {
+ md->hitend = TRUE;
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
+ }
+
/* Fall through */
+ /* Match any single character whatsoever. */
+
case OP_ALLANY:
- if (eptr++ >= md->end_subject)
- {
+ if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */
+ { /* not be updated before SCHECK_PARTIAL. */
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+ eptr++;
+#ifdef SUPPORT_UTF
+ if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+#endif
ecode++;
break;
@@ -1880,11 +2293,12 @@
any byte, even newline, independent of the setting of PCRE_DOTALL. */
case OP_ANYBYTE:
- if (eptr++ >= md->end_subject)
- {
+ if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */
+ { /* not be updated before SCHECK_PARTIAL. */
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
+ eptr++;
ecode++;
break;
@@ -1892,16 +2306,16 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
if (
-#ifdef SUPPORT_UTF8
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
c < 256 &&
#endif
(md->ctypes[c] & ctype_digit) != 0
)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
ecode++;
break;
@@ -1909,16 +2323,16 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
if (
-#ifdef SUPPORT_UTF8
- c >= 256 ||
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c > 255 ||
#endif
(md->ctypes[c] & ctype_digit) == 0
)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
ecode++;
break;
@@ -1926,16 +2340,16 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
if (
-#ifdef SUPPORT_UTF8
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
c < 256 &&
#endif
(md->ctypes[c] & ctype_space) != 0
)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
ecode++;
break;
@@ -1943,16 +2357,16 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
if (
-#ifdef SUPPORT_UTF8
- c >= 256 ||
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c > 255 ||
#endif
(md->ctypes[c] & ctype_space) == 0
)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
ecode++;
break;
@@ -1960,16 +2374,16 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
if (
-#ifdef SUPPORT_UTF8
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
c < 256 &&
#endif
(md->ctypes[c] & ctype_word) != 0
)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
ecode++;
break;
@@ -1977,16 +2391,16 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
if (
-#ifdef SUPPORT_UTF8
- c >= 256 ||
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c > 255 ||
#endif
(md->ctypes[c] & ctype_word) == 0
)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
ecode++;
break;
@@ -1994,14 +2408,19 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
+
case 0x000d:
- if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ }
+ else if (*eptr == 0x0a) eptr++;
break;
case 0x000a:
@@ -2012,7 +2431,7 @@
case 0x0085:
case 0x2028:
case 0x2029:
- if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
break;
}
ecode++;
@@ -2022,7 +2441,7 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
switch(c)
@@ -2047,7 +2466,7 @@
case 0x202f: /* NARROW NO-BREAK SPACE */
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
case 0x3000: /* IDEOGRAPHIC SPACE */
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
ecode++;
break;
@@ -2056,12 +2475,12 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
@@ -2090,7 +2509,7 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
switch(c)
@@ -2103,7 +2522,7 @@
case 0x85: /* NEL */
case 0x2028: /* LINE SEPARATOR */
case 0x2029: /* PARAGRAPH SEPARATOR */
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
ecode++;
break;
@@ -2112,12 +2531,12 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x0a: /* LF */
case 0x0b: /* VT */
case 0x0c: /* FF */
@@ -2139,7 +2558,7 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
{
@@ -2148,59 +2567,59 @@
switch(ecode[1])
{
case PT_ANY:
- if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH);
+ if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
break;
case PT_LAMP:
if ((prop->chartype == ucp_Lu ||
prop->chartype == ucp_Ll ||
prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
break;
case PT_GC:
- if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))
- MRRETURN(MATCH_NOMATCH);
+ if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
+ RRETURN(MATCH_NOMATCH);
break;
case PT_PC:
if ((ecode[2] != prop->chartype) == (op == OP_PROP))
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
break;
case PT_SC:
if ((ecode[2] != prop->script) == (op == OP_PROP))
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
break;
/* These are specials */
case PT_ALNUM:
- if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
- MRRETURN(MATCH_NOMATCH);
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
break;
case PT_SPACE: /* Perl space */
- if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
== (op == OP_NOTPROP))
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
break;
case PT_PXSPACE: /* POSIX space */
- if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
c == CHAR_FF || c == CHAR_CR)
== (op == OP_NOTPROP))
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
break;
case PT_WORD:
- if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N ||
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
break;
/* This should never occur */
@@ -2220,24 +2639,18 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
+ if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
+ while (eptr < md->end_subject)
{
- int category = UCD_CATEGORY(c);
- if (category == ucp_M) MRRETURN(MATCH_NOMATCH);
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf8) c = *eptr; else
- {
- GETCHARLEN(c, eptr, len);
- }
- category = UCD_CATEGORY(c);
- if (category != ucp_M) break;
- eptr += len;
- }
+ int len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ eptr += len;
}
+ CHECK_PARTIAL();
ecode++;
break;
#endif
@@ -2252,129 +2665,147 @@
loops). */
case OP_REF:
- {
- offset = GET2(ecode, 1) << 1; /* Doubled ref number */
- ecode += 3;
+ case OP_REFI:
+ caseless = op == OP_REFI;
+ offset = GET2(ecode, 1) << 1; /* Doubled ref number */
+ ecode += 1 + IMM2_SIZE;
- /* If the reference is unset, there are two possibilities:
+ /* If the reference is unset, there are two possibilities:
- (a) In the default, Perl-compatible state, set the length to be longer
- than the amount of subject left; this ensures that every attempt at a
- match fails. We can't just fail here, because of the possibility of
- quantifiers with zero minima.
+ (a) In the default, Perl-compatible state, set the length negative;
+ this ensures that every attempt at a match fails. We can't just fail
+ here, because of the possibility of quantifiers with zero minima.
- (b) If the JavaScript compatibility flag is set, set the length to zero
- so that the back reference matches an empty string.
+ (b) If the JavaScript compatibility flag is set, set the length to zero
+ so that the back reference matches an empty string.
- Otherwise, set the length to the length of what was matched by the
- referenced subpattern. */
+ Otherwise, set the length to the length of what was matched by the
+ referenced subpattern. */
- if (offset >= offset_top || md->offset_vector[offset] < 0)
- length = (md->jscript_compat)? 0 : (int)(md->end_subject - eptr + 1);
- else
- length = md->offset_vector[offset+1] - md->offset_vector[offset];
+ if (offset >= offset_top || md->offset_vector[offset] < 0)
+ length = (md->jscript_compat)? 0 : -1;
+ else
+ length = md->offset_vector[offset+1] - md->offset_vector[offset];
- /* Set up for repetition, or handle the non-repeated case */
+ /* Set up for repetition, or handle the non-repeated case */
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
- break;
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ c = *ecode++ - OP_CRSTAR;
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+ break;
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- minimize = (*ecode == OP_CRMINRANGE);
- min = GET2(ecode, 1);
- max = GET2(ecode, 3);
- if (max == 0) max = INT_MAX;
- ecode += 5;
- break;
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ minimize = (*ecode == OP_CRMINRANGE);
+ min = GET2(ecode, 1);
+ max = GET2(ecode, 1 + IMM2_SIZE);
+ if (max == 0) max = INT_MAX;
+ ecode += 1 + 2 * IMM2_SIZE;
+ break;
- default: /* No repeat follows */
- if (!match_ref(offset, eptr, length, md, ims))
- {
- CHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
- }
- eptr += length;
- continue; /* With the main loop */
+ default: /* No repeat follows */
+ if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
+ {
+ if (length == -2) eptr = md->end_subject; /* Partial match */
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
}
+ eptr += length;
+ continue; /* With the main loop */
+ }
- /* If the length of the reference is zero, just continue with the
- main loop. */
+ /* Handle repeated back references. If the length of the reference is
+ zero, just continue with the main loop. If the length is negative, it
+ means the reference is unset in non-Java-compatible mode. If the minimum is
+ zero, we can continue at the same level without recursion. For any other
+ minimum, carrying on will result in NOMATCH. */
- if (length == 0) continue;
+ if (length == 0) continue;
+ if (length < 0 && min == 0) continue;
- /* First, ensure the minimum number of matches are present. We get back
- the length of the reference string explicitly rather than passing the
- address of eptr, so that eptr can be a register variable. */
+ /* First, ensure the minimum number of matches are present. We get back
+ the length of the reference string explicitly rather than passing the
+ address of eptr, so that eptr can be a register variable. */
- for (i = 1; i <= min; i++)
+ for (i = 1; i <= min; i++)
+ {
+ int slength;
+ if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
{
- if (!match_ref(offset, eptr, length, md, ims))
- {
- CHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
- }
- eptr += length;
+ if (slength == -2) eptr = md->end_subject; /* Partial match */
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
}
+ eptr += slength;
+ }
- /* If min = max, continue at the same level without recursion.
- They are not both allowed to be zero. */
+ /* If min = max, continue at the same level without recursion.
+ They are not both allowed to be zero. */
- if (min == max) continue;
+ if (min == max) continue;
- /* If minimizing, keep trying and advancing the pointer */
+ /* If minimizing, keep trying and advancing the pointer */
- if (minimize)
+ if (minimize)
+ {
+ for (fi = min;; fi++)
{
- for (fi = min;; fi++)
+ int slength;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
- if (!match_ref(offset, eptr, length, md, ims))
- {
- CHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
- }
- eptr += length;
+ if (slength == -2) eptr = md->end_subject; /* Partial match */
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
}
- /* Control never gets here */
+ eptr += slength;
}
+ /* Control never gets here */
+ }
- /* If maximizing, find the longest string and work backwards */
+ /* If maximizing, find the longest string and work backwards */
- else
+ else
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
{
- pp = eptr;
- for (i = min; i < max; i++)
+ int slength;
+ if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
{
- if (!match_ref(offset, eptr, length, md, ims))
+ /* Can't use CHECK_PARTIAL because we don't want to update eptr in
+ the soft partial matching case. */
+
+ if (slength == -2 && md->partial != 0 &&
+ md->end_subject > md->start_used_ptr)
{
- CHECK_PARTIAL();
- break;
+ md->hitend = TRUE;
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
}
- eptr += length;
- }
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr -= length;
+ break;
}
- MRRETURN(MATCH_NOMATCH);
+ eptr += slength;
+ }
+
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr -= length;
}
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
@@ -2392,8 +2823,11 @@
case OP_NCLASS:
case OP_CLASS:
{
+ /* The data variable is saved across frames, so the byte map needs to
+ be stored there. */
+#define BYTE_MAP ((pcre_uint8 *)data)
data = ecode + 1; /* Save for matching */
- ecode += 33; /* Advance past the item */
+ ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
switch (*ecode)
{
@@ -2414,9 +2848,9 @@
case OP_CRMINRANGE:
minimize = (*ecode == OP_CRMINRANGE);
min = GET2(ecode, 1);
- max = GET2(ecode, 3);
+ max = GET2(ecode, 1 + IMM2_SIZE);
if (max == 0) max = INT_MAX;
- ecode += 5;
+ ecode += 1 + 2 * IMM2_SIZE;
break;
default: /* No repeat follows */
@@ -2426,41 +2860,45 @@
/* First, ensure the minimum number of matches are present. */
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
for (i = 1; i <= min; i++)
{
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(c, eptr);
if (c > 255)
{
- if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
}
else
- {
- if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
- }
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
}
}
else
#endif
- /* Not UTF-8 mode */
+ /* Not UTF mode */
{
for (i = 1; i <= min; i++)
{
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
c = *eptr++;
- if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
+#ifndef COMPILE_PCRE8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
}
}
@@ -2474,47 +2912,51 @@
if (minimize)
{
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(c, eptr);
if (c > 255)
{
- if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
}
else
- {
- if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
- }
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
}
}
else
#endif
- /* Not UTF-8 mode */
+ /* Not UTF mode */
{
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
c = *eptr++;
- if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
+#ifndef COMPILE_PCRE8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
}
}
/* Control never gets here */
@@ -2526,9 +2968,8 @@
{
pp = eptr;
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
for (i = min; i < max; i++)
{
@@ -2544,14 +2985,12 @@
if (op == OP_CLASS) break;
}
else
- {
- if ((data[c/8] & (1 << (c&7))) == 0) break;
- }
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
eptr += len;
}
for (;;)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM18);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -2559,7 +2998,7 @@
}
else
#endif
- /* Not UTF-8 mode */
+ /* Not UTF mode */
{
for (i = min; i < max; i++)
{
@@ -2569,19 +3008,27 @@
break;
}
c = *eptr;
- if ((data[c/8] & (1 << (c&7))) == 0) break;
+#ifndef COMPILE_PCRE8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) break;
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
eptr++;
}
while (eptr >= pp)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM19);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
}
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
+#undef BYTE_MAP
}
/* Control never gets here */
@@ -2590,7 +3037,7 @@
when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
mode, because Unicode properties are supported in non-UTF-8 mode. */
-#ifdef SUPPORT_UTF8
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
case OP_XCLASS:
{
data = ecode + 1 + LINK_SIZE; /* Save for matching */
@@ -2615,9 +3062,9 @@
case OP_CRMINRANGE:
minimize = (*ecode == OP_CRMINRANGE);
min = GET2(ecode, 1);
- max = GET2(ecode, 3);
+ max = GET2(ecode, 1 + IMM2_SIZE);
if (max == 0) max = INT_MAX;
- ecode += 5;
+ ecode += 1 + 2 * IMM2_SIZE;
break;
default: /* No repeat follows */
@@ -2632,10 +3079,10 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
+ if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
}
/* If max == min we can continue with the main loop without the
@@ -2650,16 +3097,16 @@
{
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
+ if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
}
@@ -2677,18 +3124,24 @@
SCHECK_PARTIAL();
break;
}
+#ifdef SUPPORT_UTF
GETCHARLENTEST(c, eptr, len);
- if (!_pcre_xclass(c, data)) break;
+#else
+ c = *eptr;
+#endif
+ if (!PRIV(xclass)(c, data, utf)) break;
eptr += len;
}
for(;;)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
- if (utf8) BACKCHAR(eptr);
+#ifdef SUPPORT_UTF
+ if (utf) BACKCHAR(eptr);
+#endif
}
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
@@ -2698,8 +3151,8 @@
/* Match a single character, casefully */
case OP_CHAR:
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
length = 1;
ecode++;
@@ -2707,50 +3160,57 @@
if (length > md->end_subject - eptr)
{
CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH);
+ while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
}
else
#endif
-
- /* Non-UTF-8 mode */
+ /* Not UTF mode */
{
if (md->end_subject - eptr < 1)
{
SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH);
+ if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
ecode += 2;
}
break;
- /* Match a single character, caselessly */
+ /* Match a single character, caselessly. If we are at the end of the
+ subject, give up immediately. */
+
+ case OP_CHARI:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
- case OP_CHARNC:
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
length = 1;
ecode++;
GETCHARLEN(fc, ecode, length);
- if (length > md->end_subject - eptr)
- {
- CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */
- MRRETURN(MATCH_NOMATCH);
- }
-
/* If the pattern character's value is < 128, we have only one byte, and
- can use the fast lookup table. */
+ we know that its other case must also be one byte long, so we can use the
+ fast lookup table. We know that there is at least one byte left in the
+ subject. */
if (fc < 128)
{
- if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+ if (md->lcc[fc]
+ != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
+ ecode++;
+ eptr++;
}
- /* Otherwise we must pick up the subject character */
+ /* Otherwise we must pick up the subject character. Note that we cannot
+ use the value of "length" to check for sufficient bytes left, because the
+ other case of the character may have more or fewer bytes. */
else
{
@@ -2766,21 +3226,18 @@
#ifdef SUPPORT_UCP
if (dc != UCD_OTHERCASE(fc))
#endif
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
}
}
else
-#endif /* SUPPORT_UTF8 */
+#endif /* SUPPORT_UTF */
- /* Non-UTF-8 mode */
+ /* Not UTF mode */
{
- if (md->end_subject - eptr < 1)
- {
- SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */
- MRRETURN(MATCH_NOMATCH);
- }
- if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+ if (TABLE_GET(ecode[1], md->lcc, ecode[1])
+ != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
+ eptr++;
ecode += 2;
}
break;
@@ -2788,23 +3245,28 @@
/* Match a single character repeatedly. */
case OP_EXACT:
+ case OP_EXACTI:
min = max = GET2(ecode, 1);
- ecode += 3;
+ ecode += 1 + IMM2_SIZE;
goto REPEATCHAR;
case OP_POSUPTO:
+ case OP_POSUPTOI:
possessive = TRUE;
/* Fall through */
case OP_UPTO:
+ case OP_UPTOI:
case OP_MINUPTO:
+ case OP_MINUPTOI:
min = 0;
max = GET2(ecode, 1);
- minimize = *ecode == OP_MINUPTO;
- ecode += 3;
+ minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
+ ecode += 1 + IMM2_SIZE;
goto REPEATCHAR;
case OP_POSSTAR:
+ case OP_POSSTARI:
possessive = TRUE;
min = 0;
max = INT_MAX;
@@ -2812,6 +3274,7 @@
goto REPEATCHAR;
case OP_POSPLUS:
+ case OP_POSPLUSI:
possessive = TRUE;
min = 1;
max = INT_MAX;
@@ -2819,6 +3282,7 @@
goto REPEATCHAR;
case OP_POSQUERY:
+ case OP_POSQUERYI:
possessive = TRUE;
min = 0;
max = 1;
@@ -2826,14 +3290,19 @@
goto REPEATCHAR;
case OP_STAR:
+ case OP_STARI:
case OP_MINSTAR:
+ case OP_MINSTARI:
case OP_PLUS:
+ case OP_PLUSI:
case OP_MINPLUS:
+ case OP_MINPLUSI:
case OP_QUERY:
+ case OP_QUERYI:
case OP_MINQUERY:
- c = *ecode++ - OP_STAR;
+ case OP_MINQUERYI:
+ c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI);
minimize = (c & 1) != 0;
-
min = rep_min[c]; /* Pick up values from tables; */
max = rep_max[c]; /* zero for max => infinity */
if (max == 0) max = INT_MAX;
@@ -2841,8 +3310,8 @@
/* Common code for all repeated single-character matches. */
REPEATCHAR:
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
length = 1;
charptr = ecode;
@@ -2856,25 +3325,25 @@
{
#ifdef SUPPORT_UCP
unsigned int othercase;
- if ((ims & PCRE_CASELESS) != 0 &&
+ if (op >= OP_STARI && /* Caseless */
(othercase = UCD_OTHERCASE(fc)) != fc)
- oclength = _pcre_ord2utf8(othercase, occhars);
+ oclength = PRIV(ord2utf)(othercase, occhars);
else oclength = 0;
#endif /* SUPPORT_UCP */
for (i = 1; i <= min; i++)
{
if (eptr <= md->end_subject - length &&
- memcmp(eptr, charptr, length) == 0) eptr += length;
+ memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
#ifdef SUPPORT_UCP
else if (oclength > 0 &&
eptr <= md->end_subject - oclength &&
- memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
+ memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
#endif /* SUPPORT_UCP */
else
{
CHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
}
@@ -2884,20 +3353,20 @@
{
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr <= md->end_subject - length &&
- memcmp(eptr, charptr, length) == 0) eptr += length;
+ memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
#ifdef SUPPORT_UCP
else if (oclength > 0 &&
eptr <= md->end_subject - oclength &&
- memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
+ memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
#endif /* SUPPORT_UCP */
else
{
CHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
}
/* Control never gets here */
@@ -2909,11 +3378,11 @@
for (i = min; i < max; i++)
{
if (eptr <= md->end_subject - length &&
- memcmp(eptr, charptr, length) == 0) eptr += length;
+ memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
#ifdef SUPPORT_UCP
else if (oclength > 0 &&
eptr <= md->end_subject - oclength &&
- memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
+ memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
#endif /* SUPPORT_UCP */
else
{
@@ -2926,9 +3395,9 @@
for(;;)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr == pp) { MRRETURN(MATCH_NOMATCH); }
+ if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
#ifdef SUPPORT_UCP
eptr--;
BACKCHAR(eptr);
@@ -2945,14 +3414,12 @@
value of fc will always be < 128. */
}
else
-#endif /* SUPPORT_UTF8 */
-
- /* When not in UTF-8 mode, load a single-byte character. */
+#endif /* SUPPORT_UTF */
+ /* When not in UTF-8 mode, load a single-byte character. */
+ fc = *ecode++;
- fc = *ecode++;
-
- /* The value of fc at this point is always less than 256, though we may or
- may not be in UTF-8 mode. The code is duplicated for the caseless and
+ /* The value of fc at this point is always one character, though we may
+ or may not be in UTF mode. The code is duplicated for the caseless and
caseful cases, for speed, since matching characters is likely to be quite
common. First, ensure the minimum number of matches are present. If min =
max, continue at the same level without recursing. Otherwise, if
@@ -2961,34 +3428,52 @@
maximizing, find the maximum number of characters and work backwards. */
DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
- max, eptr));
+ max, (char *)eptr));
- if ((ims & PCRE_CASELESS) != 0)
+ if (op >= OP_STARI) /* Caseless */
{
- fc = md->lcc[fc];
+#ifdef COMPILE_PCRE8
+ /* fc must be < 128 if UTF is enabled. */
+ foc = md->fcc[fc];
+#else
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ if (utf && fc > 127)
+ foc = UCD_OTHERCASE(fc);
+#else
+ if (utf && fc > 127)
+ foc = fc;
+#endif /* SUPPORT_UCP */
+ else
+#endif /* SUPPORT_UTF */
+ foc = TABLE_GET(fc, md->fcc, fc);
+#endif /* COMPILE_PCRE8 */
+
for (i = 1; i <= min; i++)
{
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+ if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
}
if (min == max) continue;
if (minimize)
{
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+ if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
}
/* Control never gets here */
}
@@ -3002,7 +3487,7 @@
SCHECK_PARTIAL();
break;
}
- if (fc != md->lcc[*eptr]) break;
+ if (fc != *eptr && foc != *eptr) break;
eptr++;
}
@@ -3010,11 +3495,11 @@
while (eptr >= pp)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM25);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
}
@@ -3028,9 +3513,9 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
+ if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
}
if (min == max) continue;
@@ -3039,15 +3524,15 @@
{
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
+ if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
}
@@ -3068,11 +3553,11 @@
while (eptr >= pp)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM27);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
}
/* Control never gets here */
@@ -3081,24 +3566,47 @@
checking can be multibyte. */
case OP_NOT:
+ case OP_NOTI:
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- ecode++;
- GETCHARINCTEST(c, eptr);
- if ((ims & PCRE_CASELESS) != 0)
+#ifdef SUPPORT_UTF
+ if (utf)
{
-#ifdef SUPPORT_UTF8
- if (c < 256)
-#endif
- c = md->lcc[c];
- if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH);
+ register unsigned int ch, och;
+
+ ecode++;
+ GETCHARINC(ch, ecode);
+ GETCHARINC(c, eptr);
+
+ if (op == OP_NOT)
+ {
+ if (ch == c) RRETURN(MATCH_NOMATCH);
+ }
+ else
+ {
+#ifdef SUPPORT_UCP
+ if (ch > 127)
+ och = UCD_OTHERCASE(ch);
+#else
+ if (ch > 127)
+ och = ch;
+#endif /* SUPPORT_UCP */
+ else
+ och = TABLE_GET(ch, md->fcc, ch);
+ if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
+ }
}
else
+#endif
{
- if (*ecode++ == c) MRRETURN(MATCH_NOMATCH);
+ register unsigned int ch = ecode[1];
+ c = *eptr++;
+ if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
+ RRETURN(MATCH_NOMATCH);
+ ecode += 2;
}
break;
@@ -3110,19 +3618,23 @@
about... */
case OP_NOTEXACT:
+ case OP_NOTEXACTI:
min = max = GET2(ecode, 1);
- ecode += 3;
+ ecode += 1 + IMM2_SIZE;
goto REPEATNOTCHAR;
case OP_NOTUPTO:
+ case OP_NOTUPTOI:
case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
min = 0;
max = GET2(ecode, 1);
- minimize = *ecode == OP_NOTMINUPTO;
- ecode += 3;
+ minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
+ ecode += 1 + IMM2_SIZE;
goto REPEATNOTCHAR;
case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
possessive = TRUE;
min = 0;
max = INT_MAX;
@@ -3130,6 +3642,7 @@
goto REPEATNOTCHAR;
case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
possessive = TRUE;
min = 1;
max = INT_MAX;
@@ -3137,6 +3650,7 @@
goto REPEATNOTCHAR;
case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
possessive = TRUE;
min = 0;
max = 1;
@@ -3144,19 +3658,26 @@
goto REPEATNOTCHAR;
case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
possessive = TRUE;
min = 0;
max = GET2(ecode, 1);
- ecode += 3;
+ ecode += 1 + IMM2_SIZE;
goto REPEATNOTCHAR;
case OP_NOTSTAR:
+ case OP_NOTSTARI:
case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
case OP_NOTPLUS:
+ case OP_NOTPLUSI:
case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
case OP_NOTQUERY:
+ case OP_NOTQUERYI:
case OP_NOTMINQUERY:
- c = *ecode++ - OP_NOTSTAR;
+ case OP_NOTMINQUERYI:
+ c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR);
minimize = (c & 1) != 0;
min = rep_min[c]; /* Pick up values from tables; */
max = rep_max[c]; /* zero for max => infinity */
@@ -3165,7 +3686,7 @@
/* Common code for all repeated single-byte matches. */
REPEATNOTCHAR:
- fc = *ecode++;
+ GETCHARINCTEST(fc, ecode);
/* The code is duplicated for the caseless and caseful cases, for speed,
since matching characters is likely to be quite common. First, ensure the
@@ -3176,15 +3697,24 @@
characters and work backwards. */
DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,
- max, eptr));
+ max, (char *)eptr));
- if ((ims & PCRE_CASELESS) != 0)
+ if (op >= OP_NOTSTARI) /* Caseless */
{
- fc = md->lcc[fc];
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ if (utf && fc > 127)
+ foc = UCD_OTHERCASE(fc);
+#else
+ if (utf && fc > 127)
+ foc = fc;
+#endif /* SUPPORT_UCP */
+ else
+#endif /* SUPPORT_UTF */
+ foc = TABLE_GET(fc, md->fcc, fc);
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
register unsigned int d;
for (i = 1; i <= min; i++)
@@ -3192,26 +3722,25 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(d, eptr);
- if (d < 256) d = md->lcc[d];
- if (fc == d) MRRETURN(MATCH_NOMATCH);
+ if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
}
}
else
#endif
-
- /* Not UTF-8 mode */
+ /* Not UTF mode */
{
for (i = 1; i <= min; i++)
{
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+ if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
}
}
@@ -3219,41 +3748,40 @@
if (minimize)
{
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
register unsigned int d;
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(d, eptr);
- if (d < 256) d = md->lcc[d];
- if (fc == d) MRRETURN(MATCH_NOMATCH);
+ if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
}
}
else
#endif
- /* Not UTF-8 mode */
+ /* Not UTF mode */
{
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
+ if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
}
}
/* Control never gets here */
@@ -3265,9 +3793,8 @@
{
pp = eptr;
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
register unsigned int d;
for (i = min; i < max; i++)
@@ -3279,14 +3806,13 @@
break;
}
GETCHARLEN(d, eptr, len);
- if (d < 256) d = md->lcc[d];
- if (fc == d) break;
+ if (fc == d || (unsigned int)foc == d) break;
eptr += len;
}
- if (possessive) continue;
- for(;;)
+ if (possessive) continue;
+ for(;;)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -3294,7 +3820,7 @@
}
else
#endif
- /* Not UTF-8 mode */
+ /* Not UTF mode */
{
for (i = min; i < max; i++)
{
@@ -3303,19 +3829,19 @@
SCHECK_PARTIAL();
break;
}
- if (fc == md->lcc[*eptr]) break;
+ if (fc == *eptr || foc == *eptr) break;
eptr++;
}
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM31);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
}
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
}
@@ -3324,9 +3850,8 @@
else
{
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
register unsigned int d;
for (i = 1; i <= min; i++)
@@ -3334,24 +3859,24 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(d, eptr);
- if (fc == d) MRRETURN(MATCH_NOMATCH);
+ if (fc == d) RRETURN(MATCH_NOMATCH);
}
}
else
#endif
- /* Not UTF-8 mode */
+ /* Not UTF mode */
{
for (i = 1; i <= min; i++)
{
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
+ if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
}
}
@@ -3359,40 +3884,39 @@
if (minimize)
{
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
register unsigned int d;
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(d, eptr);
- if (fc == d) MRRETURN(MATCH_NOMATCH);
+ if (fc == d) RRETURN(MATCH_NOMATCH);
}
}
else
#endif
- /* Not UTF-8 mode */
+ /* Not UTF mode */
{
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
+ if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
}
}
/* Control never gets here */
@@ -3404,9 +3928,8 @@
{
pp = eptr;
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
register unsigned int d;
for (i = min; i < max; i++)
@@ -3424,7 +3947,7 @@
if (possessive) continue;
for(;;)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM34);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -3432,7 +3955,7 @@
}
else
#endif
- /* Not UTF-8 mode */
+ /* Not UTF mode */
{
for (i = min; i < max; i++)
{
@@ -3447,13 +3970,13 @@
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM35);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
}
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
}
/* Control never gets here */
@@ -3465,7 +3988,7 @@
case OP_TYPEEXACT:
min = max = GET2(ecode, 1);
minimize = TRUE;
- ecode += 3;
+ ecode += 1 + IMM2_SIZE;
goto REPEATTYPE;
case OP_TYPEUPTO:
@@ -3473,7 +3996,7 @@
min = 0;
max = GET2(ecode, 1);
minimize = *ecode == OP_TYPEMINUPTO;
- ecode += 3;
+ ecode += 1 + IMM2_SIZE;
goto REPEATTYPE;
case OP_TYPEPOSSTAR:
@@ -3501,7 +4024,7 @@
possessive = TRUE;
min = 0;
max = GET2(ecode, 1);
- ecode += 3;
+ ecode += 1 + IMM2_SIZE;
goto REPEATTYPE;
case OP_TYPESTAR:
@@ -3547,13 +4070,13 @@
switch(prop_type)
{
case PT_ANY:
- if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
for (i = 1; i <= min; i++)
{
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
}
@@ -3562,17 +4085,18 @@
case PT_LAMP:
for (i = 1; i <= min; i++)
{
+ int chartype;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_chartype = UCD_CHARTYPE(c);
- if ((prop_chartype == ucp_Lu ||
- prop_chartype == ucp_Ll ||
- prop_chartype == ucp_Lt) == prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
}
break;
@@ -3582,12 +4106,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == prop_value) == prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
}
break;
@@ -3597,12 +4120,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_chartype = UCD_CHARTYPE(c);
- if ((prop_chartype == prop_value) == prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
}
break;
@@ -3612,28 +4134,27 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_script = UCD_SCRIPT(c);
- if ((prop_script == prop_value) == prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
}
break;
case PT_ALNUM:
for (i = 1; i <= min; i++)
{
+ int category;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_L || prop_category == ucp_N)
- == prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
}
break;
@@ -3643,14 +4164,13 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
c == CHAR_FF || c == CHAR_CR)
== prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
break;
@@ -3660,31 +4180,30 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
== prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
break;
case PT_WORD:
for (i = 1; i <= min; i++)
{
+ int category;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_L || prop_category == ucp_N ||
- c == CHAR_UNDERSCORE)
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
== prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
break;
@@ -3705,20 +4224,18 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH);
+ if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
while (eptr < md->end_subject)
{
int len = 1;
- if (!utf8) c = *eptr;
- else { GETCHARLEN(c, eptr, len); }
- prop_category = UCD_CATEGORY(c);
- if (prop_category != ucp_M) break;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
eptr += len;
}
+ CHECK_PARTIAL();
}
}
@@ -3727,8 +4244,8 @@
/* Handle all other cases when the coding is UTF-8 */
-#ifdef SUPPORT_UTF8
- if (utf8) switch(ctype)
+#ifdef SUPPORT_UTF
+ if (utf) switch(ctype)
{
case OP_ANY:
for (i = 1; i <= min; i++)
@@ -3736,11 +4253,20 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ if (md->partial != 0 &&
+ eptr + 1 >= md->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ *eptr == NLBLOCK->nl[0])
+ {
+ md->hitend = TRUE;
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
}
- if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
eptr++;
- while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
}
break;
@@ -3750,15 +4276,15 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
eptr++;
- while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
}
break;
case OP_ANYBYTE:
- if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH);
+ if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
eptr += min;
break;
@@ -3768,12 +4294,13 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(c, eptr);
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
+
case 0x000d:
if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
break;
@@ -3786,7 +4313,7 @@
case 0x0085:
case 0x2028:
case 0x2029:
- if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
break;
}
}
@@ -3798,7 +4325,7 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(c, eptr);
switch(c)
@@ -3823,7 +4350,7 @@
case 0x202f: /* NARROW NO-BREAK SPACE */
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
case 0x3000: /* IDEOGRAPHIC SPACE */
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
}
break;
@@ -3834,12 +4361,12 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(c, eptr);
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
@@ -3870,7 +4397,7 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(c, eptr);
switch(c)
@@ -3883,7 +4410,7 @@
case 0x85: /* NEL */
case 0x2028: /* LINE SEPARATOR */
case 0x2029: /* PARAGRAPH SEPARATOR */
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
}
break;
@@ -3894,12 +4421,12 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(c, eptr);
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x0a: /* LF */
case 0x0b: /* VT */
case 0x0c: /* FF */
@@ -3918,11 +4445,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINC(c, eptr);
if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
break;
@@ -3932,10 +4459,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
- MRRETURN(MATCH_NOMATCH);
+ if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
/* No need to skip more bytes - we know it's a 1-byte character */
}
break;
@@ -3946,11 +4474,12 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
- MRRETURN(MATCH_NOMATCH);
- while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
}
break;
@@ -3960,10 +4489,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
- MRRETURN(MATCH_NOMATCH);
+ if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
/* No need to skip more bytes - we know it's a 1-byte character */
}
break;
@@ -3974,11 +4504,12 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
- MRRETURN(MATCH_NOMATCH);
- while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
}
break;
@@ -3988,10 +4519,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
- MRRETURN(MATCH_NOMATCH);
+ if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
/* No need to skip more bytes - we know it's a 1-byte character */
}
break;
@@ -4001,7 +4533,7 @@
} /* End switch(ctype) */
else
-#endif /* SUPPORT_UTF8 */
+#endif /* SUPPORT_UTF */
/* Code for the non-UTF-8 case for minimum matching of operators other
than OP_PROP and OP_NOTPROP. */
@@ -4013,10 +4545,19 @@
{
if (eptr >= md->end_subject)
{
- SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ if (md->partial != 0 &&
+ eptr + 1 >= md->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ *eptr == NLBLOCK->nl[0])
+ {
+ md->hitend = TRUE;
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
}
- if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
eptr++;
}
break;
@@ -4025,7 +4566,7 @@
if (eptr > md->end_subject - min)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
eptr += min;
break;
@@ -4034,7 +4575,7 @@
if (eptr > md->end_subject - min)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
eptr += min;
break;
@@ -4045,21 +4586,27 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
switch(*eptr++)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
+
case 0x000d:
if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
break;
+
case 0x000a:
break;
case 0x000b:
case 0x000c:
case 0x0085:
- if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
+#ifdef COMPILE_PCRE16
+ case 0x2028:
+ case 0x2029:
+#endif
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
break;
}
}
@@ -4071,7 +4618,7 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
switch(*eptr++)
{
@@ -4079,7 +4626,25 @@
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
- MRRETURN(MATCH_NOMATCH);
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
+ RRETURN(MATCH_NOMATCH);
}
}
break;
@@ -4090,14 +4655,32 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
switch(*eptr++)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
break;
}
}
@@ -4109,7 +4692,7 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
switch(*eptr++)
{
@@ -4119,7 +4702,11 @@
case 0x0c: /* FF */
case 0x0d: /* CR */
case 0x85: /* NEL */
- MRRETURN(MATCH_NOMATCH);
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
+ RRETURN(MATCH_NOMATCH);
}
}
break;
@@ -4130,16 +4717,20 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
switch(*eptr++)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x0a: /* LF */
case 0x0b: /* VT */
case 0x0c: /* FF */
case 0x0d: /* CR */
case 0x85: /* NEL */
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
break;
}
}
@@ -4151,9 +4742,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
}
break;
@@ -4163,9 +4756,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
}
break;
@@ -4175,9 +4770,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
}
break;
@@ -4187,9 +4784,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
}
break;
@@ -4199,10 +4798,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if ((md->ctypes[*eptr++] & ctype_word) != 0)
- MRRETURN(MATCH_NOMATCH);
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
}
break;
@@ -4212,10 +4812,11 @@
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
- if ((md->ctypes[*eptr++] & ctype_word) == 0)
- MRRETURN(MATCH_NOMATCH);
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
}
break;
@@ -4242,170 +4843,167 @@
case PT_ANY:
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
case PT_LAMP:
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
+ int chartype;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_chartype = UCD_CHARTYPE(c);
- if ((prop_chartype == ucp_Lu ||
- prop_chartype == ucp_Ll ||
- prop_chartype == ucp_Lt) == prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
case PT_GC:
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == prop_value) == prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
case PT_PC:
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_chartype = UCD_CHARTYPE(c);
- if ((prop_chartype == prop_value) == prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
case PT_SC:
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_script = UCD_SCRIPT(c);
- if ((prop_script == prop_value) == prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
case PT_ALNUM:
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM59);
+ int category;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_L || prop_category == ucp_N)
- == prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
case PT_SPACE: /* Perl space */
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM60);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
c == CHAR_FF || c == CHAR_CR)
== prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
case PT_PXSPACE: /* POSIX space */
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM61);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
== prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
case PT_WORD:
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM62);
+ int category;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_L ||
- prop_category == ucp_N ||
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L ||
+ category == ucp_N ||
c == CHAR_UNDERSCORE)
== prop_fail_result)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
@@ -4423,52 +5021,59 @@
{
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH);
+ if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
while (eptr < md->end_subject)
{
int len = 1;
- if (!utf8) c = *eptr;
- else { GETCHARLEN(c, eptr, len); }
- prop_category = UCD_CATEGORY(c);
- if (prop_category != ucp_M) break;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
eptr += len;
}
+ CHECK_PARTIAL();
}
}
-
else
#endif /* SUPPORT_UCP */
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
if (ctype == OP_ANY && IS_NEWLINE(eptr))
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
switch(ctype)
{
- case OP_ANY: /* This is the non-NL case */
+ case OP_ANY: /* This is the non-NL case */
+ if (md->partial != 0 && /* Take care with CRLF partial */
+ eptr >= md->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ md->hitend = TRUE;
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
+ }
+ break;
+
case OP_ALLANY:
case OP_ANYBYTE:
break;
@@ -4476,7 +5081,7 @@
case OP_ANYNL:
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x000d:
if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
break;
@@ -4488,7 +5093,7 @@
case 0x0085:
case 0x2028:
case 0x2029:
- if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
break;
}
break;
@@ -4516,14 +5121,14 @@
case 0x202f: /* NARROW NO-BREAK SPACE */
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
case 0x3000: /* IDEOGRAPHIC SPACE */
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
break;
case OP_HSPACE:
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
@@ -4558,14 +5163,14 @@
case 0x85: /* NEL */
case 0x2028: /* LINE SEPARATOR */
case 0x2029: /* PARAGRAPH SEPARATOR */
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
break;
case OP_VSPACE:
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x0a: /* LF */
case 0x0b: /* VT */
case 0x0c: /* FF */
@@ -4579,32 +5184,32 @@
case OP_NOT_DIGIT:
if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
break;
case OP_DIGIT:
if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
break;
case OP_NOT_WHITESPACE:
if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
break;
case OP_WHITESPACE:
- if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
- MRRETURN(MATCH_NOMATCH);
+ if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
break;
case OP_NOT_WORDCHAR:
if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
break;
case OP_WORDCHAR:
if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
break;
default:
@@ -4614,24 +5219,35 @@
}
else
#endif
- /* Not UTF-8 mode */
+ /* Not UTF mode */
{
for (fi = min;; fi++)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) MRRETURN(MATCH_NOMATCH);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
if (ctype == OP_ANY && IS_NEWLINE(eptr))
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
c = *eptr++;
switch(ctype)
{
- case OP_ANY: /* This is the non-NL case */
+ case OP_ANY: /* This is the non-NL case */
+ if (md->partial != 0 && /* Take care with CRLF partial */
+ eptr >= md->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ c == NLBLOCK->nl[0])
+ {
+ md->hitend = TRUE;
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
+ }
+ break;
+
case OP_ALLANY:
case OP_ANYBYTE:
break;
@@ -4639,7 +5255,7 @@
case OP_ANYNL:
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x000d:
if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
break;
@@ -4650,7 +5266,11 @@
case 0x000b:
case 0x000c:
case 0x0085:
- if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
+#ifdef COMPILE_PCRE16
+ case 0x2028:
+ case 0x2029:
+#endif
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
break;
}
break;
@@ -4662,17 +5282,53 @@
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
- MRRETURN(MATCH_NOMATCH);
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
+ RRETURN(MATCH_NOMATCH);
}
break;
case OP_HSPACE:
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
break;
}
break;
@@ -4686,45 +5342,53 @@
case 0x0c: /* FF */
case 0x0d: /* CR */
case 0x85: /* NEL */
- MRRETURN(MATCH_NOMATCH);
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
+ RRETURN(MATCH_NOMATCH);
}
break;
case OP_VSPACE:
switch(c)
{
- default: MRRETURN(MATCH_NOMATCH);
+ default: RRETURN(MATCH_NOMATCH);
case 0x0a: /* LF */
case 0x0b: /* VT */
case 0x0c: /* FF */
case 0x0d: /* CR */
case 0x85: /* NEL */
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
break;
}
break;
case OP_NOT_DIGIT:
- if ((md->ctypes[c] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);
+ if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
break;
case OP_DIGIT:
- if ((md->ctypes[c] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);
+ if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
break;
case OP_NOT_WHITESPACE:
- if ((md->ctypes[c] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);
+ if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
break;
case OP_WHITESPACE:
- if ((md->ctypes[c] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);
+ if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
break;
case OP_NOT_WORDCHAR:
- if ((md->ctypes[c] & ctype_word) != 0) MRRETURN(MATCH_NOMATCH);
+ if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
break;
case OP_WORDCHAR:
- if ((md->ctypes[c] & ctype_word) == 0) MRRETURN(MATCH_NOMATCH);
+ if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
break;
default:
@@ -4766,6 +5430,7 @@
case PT_LAMP:
for (i = min; i < max; i++)
{
+ int chartype;
int len = 1;
if (eptr >= md->end_subject)
{
@@ -4773,10 +5438,10 @@
break;
}
GETCHARLENTEST(c, eptr, len);
- prop_chartype = UCD_CHARTYPE(c);
- if ((prop_chartype == ucp_Lu ||
- prop_chartype == ucp_Ll ||
- prop_chartype == ucp_Lt) == prop_fail_result)
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
break;
eptr+= len;
}
@@ -4792,9 +5457,7 @@
break;
}
GETCHARLENTEST(c, eptr, len);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == prop_value) == prop_fail_result)
- break;
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break;
eptr+= len;
}
break;
@@ -4809,9 +5472,7 @@
break;
}
GETCHARLENTEST(c, eptr, len);
- prop_chartype = UCD_CHARTYPE(c);
- if ((prop_chartype == prop_value) == prop_fail_result)
- break;
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break;
eptr+= len;
}
break;
@@ -4826,9 +5487,7 @@
break;
}
GETCHARLENTEST(c, eptr, len);
- prop_script = UCD_SCRIPT(c);
- if ((prop_script == prop_value) == prop_fail_result)
- break;
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break;
eptr+= len;
}
break;
@@ -4836,6 +5495,7 @@
case PT_ALNUM:
for (i = min; i < max; i++)
{
+ int category;
int len = 1;
if (eptr >= md->end_subject)
{
@@ -4843,9 +5503,8 @@
break;
}
GETCHARLENTEST(c, eptr, len);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_L || prop_category == ucp_N)
- == prop_fail_result)
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
break;
eptr+= len;
}
@@ -4861,8 +5520,7 @@
break;
}
GETCHARLENTEST(c, eptr, len);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
c == CHAR_FF || c == CHAR_CR)
== prop_fail_result)
break;
@@ -4880,8 +5538,7 @@
break;
}
GETCHARLENTEST(c, eptr, len);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
== prop_fail_result)
break;
@@ -4892,6 +5549,7 @@
case PT_WORD:
for (i = min; i < max; i++)
{
+ int category;
int len = 1;
if (eptr >= md->end_subject)
{
@@ -4899,8 +5557,8 @@
break;
}
GETCHARLENTEST(c, eptr, len);
- prop_category = UCD_CATEGORY(c);
- if ((prop_category == ucp_L || prop_category == ucp_N ||
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N ||
c == CHAR_UNDERSCORE) == prop_fail_result)
break;
eptr+= len;
@@ -4916,10 +5574,10 @@
if (possessive) continue;
for(;;)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
- if (utf8) BACKCHAR(eptr);
+ if (utf) BACKCHAR(eptr);
}
}
@@ -4930,25 +5588,23 @@
{
for (i = min; i < max; i++)
{
+ int len = 1;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
break;
}
- GETCHARINCTEST(c, eptr);
- prop_category = UCD_CATEGORY(c);
- if (prop_category == ucp_M) break;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) == ucp_M) break;
+ eptr += len;
while (eptr < md->end_subject)
{
- int len = 1;
- if (!utf8) c = *eptr; else
- {
- GETCHARLEN(c, eptr, len);
- }
- prop_category = UCD_CATEGORY(c);
- if (prop_category != ucp_M) break;
+ len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
eptr += len;
}
+ CHECK_PARTIAL();
}
/* eptr is now past the end of the maximum run */
@@ -4957,19 +5613,17 @@
for(;;)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM45);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
for (;;) /* Move back over one extended */
{
- int len = 1;
- if (!utf8) c = *eptr; else
+ if (!utf) c = *eptr; else
{
BACKCHAR(eptr);
- GETCHARLEN(c, eptr, len);
+ GETCHAR(c, eptr);
}
- prop_category = UCD_CATEGORY(c);
- if (prop_category != ucp_M) break;
+ if (UCD_CATEGORY(c) != ucp_M) break;
eptr--;
}
}
@@ -4978,10 +5632,8 @@
else
#endif /* SUPPORT_UCP */
-#ifdef SUPPORT_UTF8
- /* UTF-8 mode */
-
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
switch(ctype)
{
@@ -4996,8 +5648,17 @@
break;
}
if (IS_NEWLINE(eptr)) break;
+ if (md->partial != 0 && /* Take care with CRLF partial */
+ eptr + 1 >= md->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ *eptr == NLBLOCK->nl[0])
+ {
+ md->hitend = TRUE;
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
+ }
eptr++;
- while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
}
}
@@ -5013,8 +5674,17 @@
break;
}
if (IS_NEWLINE(eptr)) break;
+ if (md->partial != 0 && /* Take care with CRLF partial */
+ eptr + 1 >= md->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ *eptr == NLBLOCK->nl[0])
+ {
+ md->hitend = TRUE;
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
+ }
eptr++;
- while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
}
}
break;
@@ -5030,10 +5700,14 @@
break;
}
eptr++;
- while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
}
}
- else eptr = md->end_subject; /* Unlimited UTF-8 repeat */
+ else
+ {
+ eptr = md->end_subject; /* Unlimited UTF-8 repeat */
+ SCHECK_PARTIAL();
+ }
break;
/* The byte case is the same as non-UTF8 */
@@ -5241,21 +5915,26 @@
RRETURN(PCRE_ERROR_INTERNAL);
}
- /* eptr is now past the end of the maximum run */
+ /* eptr is now past the end of the maximum run. If possessive, we are
+ done (no backing up). Otherwise, match at this position; anything other
+ than no match is immediately returned. For nomatch, back up one
+ character, unless we are matching \R and the last thing matched was
+ \r\n, in which case, back up two bytes. */
if (possessive) continue;
for(;;)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM46);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
+ if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' &&
+ eptr[-1] == '\r') eptr--;
}
}
else
-#endif /* SUPPORT_UTF8 */
-
- /* Not UTF-8 mode */
+#endif /* SUPPORT_UTF */
+ /* Not UTF mode */
{
switch(ctype)
{
@@ -5268,6 +5947,15 @@
break;
}
if (IS_NEWLINE(eptr)) break;
+ if (md->partial != 0 && /* Take care with CRLF partial */
+ eptr + 1 >= md->end_subject &&
+ NLBLOCK->nltype == NLTYPE_FIXED &&
+ NLBLOCK->nllen == 2 &&
+ *eptr == NLBLOCK->nl[0])
+ {
+ md->hitend = TRUE;
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
+ }
eptr++;
}
break;
@@ -5299,10 +5987,12 @@
}
else
{
- if (c != 0x000a &&
- (md->bsr_anycrlf ||
- (c != 0x000b && c != 0x000c && c != 0x0085)))
- break;
+ if (c != 0x000a && (md->bsr_anycrlf ||
+ (c != 0x000b && c != 0x000c && c != 0x0085
+#ifdef COMPILE_PCRE16
+ && c != 0x2028 && c != 0x2029
+#endif
+ ))) break;
eptr++;
}
}
@@ -5317,7 +6007,12 @@
break;
}
c = *eptr;
- if (c == 0x09 || c == 0x20 || c == 0xa0) break;
+ if (c == 0x09 || c == 0x20 || c == 0xa0
+#ifdef COMPILE_PCRE16
+ || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A)
+ || c == 0x202f || c == 0x205f || c == 0x3000
+#endif
+ ) break;
eptr++;
}
break;
@@ -5331,7 +6026,12 @@
break;
}
c = *eptr;
- if (c != 0x09 && c != 0x20 && c != 0xa0) break;
+ if (c != 0x09 && c != 0x20 && c != 0xa0
+#ifdef COMPILE_PCRE16
+ && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A)
+ && c != 0x202f && c != 0x205f && c != 0x3000
+#endif
+ ) break;
eptr++;
}
break;
@@ -5345,8 +6045,11 @@
break;
}
c = *eptr;
- if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)
- break;
+ if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85
+#ifdef COMPILE_PCRE16
+ || c == 0x2028 || c == 0x2029
+#endif
+ ) break;
eptr++;
}
break;
@@ -5360,8 +6063,11 @@
break;
}
c = *eptr;
- if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)
- break;
+ if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85
+#ifdef COMPILE_PCRE16
+ && c != 0x2028 && c != 0x2029
+#endif
+ ) break;
eptr++;
}
break;
@@ -5374,7 +6080,7 @@
SCHECK_PARTIAL();
break;
}
- if ((md->ctypes[*eptr] & ctype_digit) != 0) break;
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break;
eptr++;
}
break;
@@ -5387,7 +6093,7 @@
SCHECK_PARTIAL();
break;
}
- if ((md->ctypes[*eptr] & ctype_digit) == 0) break;
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break;
eptr++;
}
break;
@@ -5400,7 +6106,7 @@
SCHECK_PARTIAL();
break;
}
- if ((md->ctypes[*eptr] & ctype_space) != 0) break;
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break;
eptr++;
}
break;
@@ -5413,7 +6119,7 @@
SCHECK_PARTIAL();
break;
}
- if ((md->ctypes[*eptr] & ctype_space) == 0) break;
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break;
eptr++;
}
break;
@@ -5426,7 +6132,7 @@
SCHECK_PARTIAL();
break;
}
- if ((md->ctypes[*eptr] & ctype_word) != 0) break;
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break;
eptr++;
}
break;
@@ -5439,7 +6145,7 @@
SCHECK_PARTIAL();
break;
}
- if ((md->ctypes[*eptr] & ctype_word) == 0) break;
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break;
eptr++;
}
break;
@@ -5448,20 +6154,26 @@
RRETURN(PCRE_ERROR_INTERNAL);
}
- /* eptr is now past the end of the maximum run */
+ /* eptr is now past the end of the maximum run. If possessive, we are
+ done (no backing up). Otherwise, match at this position; anything other
+ than no match is immediately returned. For nomatch, back up one
+ character (byte), unless we are matching \R and the last thing matched
+ was \r\n, in which case, back up two bytes. */
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47);
- eptr--;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' &&
+ eptr[-1] == '\r') eptr--;
}
}
/* Get here if we can't make it match with any permitted repetitions */
- MRRETURN(MATCH_NOMATCH);
+ RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
@@ -5494,17 +6206,25 @@
LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
- LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58)
-#ifdef SUPPORT_UTF8
- LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)
+ LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64)
+ LBL(65) LBL(66)
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ LBL(21)
+#endif
+#ifdef SUPPORT_UTF
+ LBL(16) LBL(18) LBL(20)
+ LBL(22) LBL(23) LBL(28) LBL(30)
LBL(32) LBL(34) LBL(42) LBL(46)
#ifdef SUPPORT_UCP
LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
LBL(59) LBL(60) LBL(61) LBL(62)
#endif /* SUPPORT_UCP */
-#endif /* SUPPORT_UTF8 */
+#endif /* SUPPORT_UTF */
default:
DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
+
+printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere);
+
return PCRE_ERROR_INTERNAL;
}
#undef LBL
@@ -5523,7 +6243,6 @@
#undef ecode
#undef mstart
#undef offset_top
-#undef ims
#undef eptrb
#undef flags
@@ -5541,8 +6260,6 @@
#undef condition
#undef prev_is_word
-#undef original_ims
-
#undef ctype
#undef length
#undef max
@@ -5569,6 +6286,31 @@
***************************************************************************/
+#ifdef NO_RECURSE
+/*************************************************
+* Release allocated heap frames *
+*************************************************/
+
+/* This function releases all the allocated frames. The base frame is on the
+machine stack, and so must not be freed.
+
+Argument: the address of the base frame
+Returns: nothing
+*/
+
+static void
+release_match_heapframes (heapframe *frame_base)
+{
+heapframe *nextframe = frame_base->Xnextframe;
+while (nextframe != NULL)
+ {
+ heapframe *oldframe = nextframe;
+ nextframe = nextframe->Xnextframe;
+ (PUBL(stack_free))(oldframe);
+ }
+}
+#endif
+
/*************************************************
* Execute a Regular Expression *
@@ -5594,52 +6336,150 @@
< -1 => some kind of unexpected problem
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
int offsetcount)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
+ PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
+ int offsetcount)
+#endif
{
-int rc, resetcount, ocount;
-int first_byte = -1;
-int req_byte = -1;
-int req_byte2 = -1;
+int rc, ocount, arg_offset_max;
int newline;
-unsigned long int ims;
BOOL using_temporary_offsets = FALSE;
BOOL anchored;
BOOL startline;
BOOL firstline;
-BOOL first_byte_caseless = FALSE;
-BOOL req_byte_caseless = FALSE;
-BOOL utf8;
+BOOL utf;
+BOOL has_first_char = FALSE;
+BOOL has_req_char = FALSE;
+pcre_uchar first_char = 0;
+pcre_uchar first_char2 = 0;
+pcre_uchar req_char = 0;
+pcre_uchar req_char2 = 0;
match_data match_block;
match_data *md = &match_block;
-const uschar *tables;
-const uschar *start_bits = NULL;
-USPTR start_match = (USPTR)subject + start_offset;
-USPTR end_subject;
-USPTR start_partial = NULL;
-USPTR req_byte_ptr = start_match - 1;
+const pcre_uint8 *tables;
+const pcre_uint8 *start_bits = NULL;
+PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;
+PCRE_PUCHAR end_subject;
+PCRE_PUCHAR start_partial = NULL;
+PCRE_PUCHAR req_char_ptr = start_match - 1;
-pcre_study_data internal_study;
const pcre_study_data *study;
+const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
+
+#ifdef NO_RECURSE
+heapframe frame_zero;
+frame_zero.Xprevframe = NULL; /* Marks the top level */
+frame_zero.Xnextframe = NULL; /* None are allocated yet */
+md->match_frames_base = &frame_zero;
+#endif
+
+/* Check for the special magic call that measures the size of the stack used
+per recursive call of match(). Without the funny casting for sizeof, a Windows
+compiler gave this error: "unary minus operator applied to unsigned type,
+result still unsigned". Hopefully the cast fixes that. */
-real_pcre internal_re;
-const real_pcre *external_re = (const real_pcre *)argument_re;
-const real_pcre *re = external_re;
+if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
+ start_offset == -999)
+#ifdef NO_RECURSE
+ return -((int)sizeof(heapframe));
+#else
+ return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
+#endif
/* Plausibility checks */
if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
-if (re == NULL || subject == NULL ||
- (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
+if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
+ return PCRE_ERROR_NULL;
if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
-/* This information is for finding all the numbers associated with a given
-name, for condition testing. */
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
+REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
+means that the pattern is likely compiled with different endianness. */
+
+if (re->magic_number != MAGIC_NUMBER)
+ return re->magic_number == REVERSED_MAGIC_NUMBER?
+ PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
+/* These two settings are used in the code for checking a UTF-8 string that
+follows immediately afterwards. Other values in the md block are used only
+during "normal" pcre_exec() processing, not when the JIT support is in use,
+so they are set up later. */
+
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+utf = md->utf = (re->options & PCRE_UTF8) != 0;
+md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
+ ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
+
+/* Check a UTF-8 string if required. Pass back the character offset and error
+code for an invalid string if a results vector is available. */
+
+#ifdef SUPPORT_UTF
+if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
+ {
+ int erroroffset;
+ int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset);
+ if (errorcode != 0)
+ {
+ if (offsetcount >= 2)
+ {
+ offsets[0] = erroroffset;
+ offsets[1] = errorcode;
+ }
+#ifdef COMPILE_PCRE16
+ return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)?
+ PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
+#else
+ return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?
+ PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
+#endif
+ }
+
+ /* Check that a start_offset points to the start of a UTF character. */
+ if (start_offset > 0 && start_offset < length &&
+ NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
+ return PCRE_ERROR_BADUTF8_OFFSET;
+ }
+#endif
+
+/* If the pattern was successfully studied with JIT support, run the JIT
+executable instead of the rest of this function. Most options must be set at
+compile time for the JIT code to be usable. Fallback to the normal code path if
+an unsupported flag is set. */
+
+#ifdef SUPPORT_JIT
+if (extra_data != NULL
+ && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT |
+ PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT
+ && extra_data->executable_jit != NULL
+ && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
+ PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART |
+ PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0)
+ {
+ rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length,
+ start_offset, options, offsets, offsetcount);
+
+ /* PCRE_ERROR_NULL means that the selected normal or partial matching
+ mode is not compiled. In this case we simply fallback to interpreter. */
+
+ if (rc != PCRE_ERROR_NULL) return rc;
+ }
+#endif
-md->name_table = (uschar *)re + re->name_table_offset;
+/* Carry on with non-JIT matching. This information is for finding all the
+numbers associated with a given name, for condition testing. */
+
+md->name_table = (pcre_uchar *)re + re->name_table_offset;
md->name_count = re->name_count;
md->name_entry_size = re->name_entry_size;
@@ -5653,7 +6493,7 @@
/* The table pointer is always in native byte order. */
-tables = external_re->tables;
+tables = re->tables;
if (extra_data != NULL)
{
@@ -5673,19 +6513,7 @@
is a feature that makes it possible to save compiled regex and re-use them
in other programs later. */
-if (tables == NULL) tables = _pcre_default_tables;
-
-/* Check that the first field in the block is the magic number. If it is not,
-test for a regex that was compiled on a host of opposite endianness. If this is
-the case, flipped values are put in internal_re and internal_study if there was
-study data too. */
-
-if (re->magic_number != MAGIC_NUMBER)
- {
- re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
- if (re == NULL) return PCRE_ERROR_BADMAGIC;
- if (study != NULL) study = &internal_study;
- }
+if (tables == NULL) tables = PRIV(default_tables);
/* Set up other data */
@@ -5695,31 +6523,35 @@
/* The code starts after the real_pcre block and the capture name table. */
-md->start_code = (const uschar *)external_re + re->name_table_offset +
+md->start_code = (const pcre_uchar *)re + re->name_table_offset +
re->name_count * re->name_entry_size;
-md->start_subject = (USPTR)subject;
+md->start_subject = (PCRE_PUCHAR)subject;
md->start_offset = start_offset;
md->end_subject = md->start_subject + length;
end_subject = md->end_subject;
md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
-utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;
md->use_ucp = (re->options & PCRE_UCP) != 0;
md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
+md->ignore_skip_arg = FALSE;
+
+/* Some options are unpacked into BOOL variables in the hope that testing
+them will be faster than individual option bits. */
md->notbol = (options & PCRE_NOTBOL) != 0;
md->noteol = (options & PCRE_NOTEOL) != 0;
md->notempty = (options & PCRE_NOTEMPTY) != 0;
md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
-md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
- ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
+
md->hitend = FALSE;
-md->mark = NULL; /* In case never set */
+md->mark = md->nomatch_mark = NULL; /* In case never set */
md->recursive = NULL; /* No recursion at top level */
+md->hasthen = (re->flags & PCRE_HASTHEN) != 0;
md->lcc = tables + lcc_offset;
+md->fcc = tables + fcc_offset;
md->ctypes = tables + ctypes_offset;
/* Handle different \R options. */
@@ -5795,41 +6627,18 @@
if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
return PCRE_ERROR_BADPARTIAL;
-/* Check a UTF-8 string if required. Unfortunately there's no way of passing
-back the character offset. */
-
-#ifdef SUPPORT_UTF8
-if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
- {
- int tb;
- if ((tb = _pcre_valid_utf8((USPTR)subject, length)) >= 0)
- return (tb == length && md->partial > 1)?
- PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
- if (start_offset > 0 && start_offset < length)
- {
- tb = ((USPTR)subject)[start_offset] & 0xc0;
- if (tb == 0x80) return PCRE_ERROR_BADUTF8_OFFSET;
- }
- }
-#endif
-
-/* The ims options can vary during the matching as a result of the presence
-of (?ims) items in the pattern. They are kept in a local variable so that
-restoring at the exit of a group is easy. */
-
-ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL);
-
/* If the expression has got more back references than the offsets supplied can
hold, we get a temporary chunk of working store to use during the matching.
Otherwise, we can use the vector supplied, rounding down its size to a multiple
of 3. */
ocount = offsetcount - (offsetcount % 3);
+arg_offset_max = (2*ocount)/3;
if (re->top_backref > 0 && re->top_backref >= ocount/3)
{
ocount = re->top_backref * 3 + 3;
- md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
+ md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int));
if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
using_temporary_offsets = TRUE;
DPRINTF(("Got memory to hold back references\n"));
@@ -5841,25 +6650,22 @@
md->offset_overflow = FALSE;
md->capture_last = -1;
-/* Compute the minimum number of offsets that we need to reset each time. Doing
-this makes a huge difference to execution time when there aren't many brackets
-in the pattern. */
-
-resetcount = 2 + re->top_bracket * 2;
-if (resetcount > offsetcount) resetcount = ocount;
-
/* Reset the working variable associated with each extraction. These should
never be used unless previously set, but they get saved and restored, and so we
-initialize them to avoid reading uninitialized locations. */
+initialize them to avoid reading uninitialized locations. Also, unset the
+offsets for the matched string. This is really just for tidiness with callouts,
+in case they inspect these fields. */
if (md->offset_vector != NULL)
{
register int *iptr = md->offset_vector + ocount;
- register int *iend = iptr - resetcount/2 + 1;
+ register int *iend = iptr - re->top_bracket;
+ if (iend < md->offset_vector + 2) iend = md->offset_vector + 2;
while (--iptr >= iend) *iptr = -1;
+ md->offset_vector[0] = md->offset_vector[1] = -1;
}
-/* Set up the first character to match, if available. The first_byte value is
+/* Set up the first character to match, if available. The first_char value is
never set for an anchored regular expression, but the anchoring may be forced
at run time, so we have to test for anchoring. The first char may be unset for
an unanchored pattern, of course. If there's no first char and the pattern was
@@ -5869,9 +6675,16 @@
{
if ((re->flags & PCRE_FIRSTSET) != 0)
{
- first_byte = re->first_byte & 255;
- if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)
- first_byte = md->lcc[first_byte];
+ has_first_char = TRUE;
+ first_char = first_char2 = (pcre_uchar)(re->first_char);
+ if ((re->flags & PCRE_FCH_CASELESS) != 0)
+ {
+ first_char2 = TABLE_GET(first_char, md->fcc, first_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && first_char > 127)
+ first_char2 = UCD_OTHERCASE(first_char);
+#endif
+ }
}
else
if (!startline && study != NULL &&
@@ -5884,9 +6697,16 @@
if ((re->flags & PCRE_REQCHSET) != 0)
{
- req_byte = re->req_byte & 255;
- req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;
- req_byte2 = (tables + fcc_offset)[req_byte]; /* case flipped */
+ has_req_char = TRUE;
+ req_char = req_char2 = (pcre_uchar)(re->req_char);
+ if ((re->flags & PCRE_RCH_CASELESS) != 0)
+ {
+ req_char2 = TABLE_GET(req_char, md->fcc, req_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && req_char > 127)
+ req_char2 = UCD_OTHERCASE(req_char);
+#endif
+ }
}
@@ -5897,17 +6717,8 @@
for(;;)
{
- USPTR save_end_subject = end_subject;
- USPTR new_start_match;
-
- /* Reset the maximum number of extractions we might see. */
-
- if (md->offset_vector != NULL)
- {
- register int *iptr = md->offset_vector;
- register int *iend = iptr + resetcount;
- while (iptr < iend) *iptr++ = -1;
- }
+ PCRE_PUCHAR save_end_subject = end_subject;
+ PCRE_PUCHAR new_start_match;
/* If firstline is TRUE, the start of the match is constrained to the first
line of a multiline string. That is, the match must be before or at the first
@@ -5917,14 +6728,14 @@
if (firstline)
{
- USPTR t = start_match;
-#ifdef SUPPORT_UTF8
- if (utf8)
+ PCRE_PUCHAR t = start_match;
+#ifdef SUPPORT_UTF
+ if (utf)
{
while (t < md->end_subject && !IS_NEWLINE(t))
{
t++;
- while (t < end_subject && (*t & 0xc0) == 0x80) t++;
+ ACROSSCHAR(t < end_subject, *t, t++);
}
}
else
@@ -5941,15 +6752,16 @@
if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
{
- /* Advance to a unique first byte if there is one. */
+ /* Advance to a unique first char if there is one. */
- if (first_byte >= 0)
+ if (has_first_char)
{
- if (first_byte_caseless)
- while (start_match < end_subject && md->lcc[*start_match] != first_byte)
+ if (first_char != first_char2)
+ while (start_match < end_subject &&
+ *start_match != first_char && *start_match != first_char2)
start_match++;
else
- while (start_match < end_subject && *start_match != first_byte)
+ while (start_match < end_subject && *start_match != first_char)
start_match++;
}
@@ -5959,14 +6771,14 @@
{
if (start_match > md->start_subject + start_offset)
{
-#ifdef SUPPORT_UTF8
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
while (start_match < end_subject && !WAS_NEWLINE(start_match))
{
start_match++;
- while(start_match < end_subject && (*start_match & 0xc0) == 0x80)
- start_match++;
+ ACROSSCHAR(start_match < end_subject, *start_match,
+ start_match++);
}
}
else
@@ -5993,13 +6805,18 @@
while (start_match < end_subject)
{
register unsigned int c = *start_match;
+#ifndef COMPILE_PCRE8
+ if (c > 255) c = 255;
+#endif
if ((start_bits[c/8] & (1 << (c&7))) == 0)
{
start_match++;
-#ifdef SUPPORT_UTF8
- if (utf8)
- while(start_match < end_subject && (*start_match & 0xc0) == 0x80)
- start_match++;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ /* In non 8-bit mode, the iteration will stop for
+ characters > 255 at the beginning or not stop at all. */
+ if (utf)
+ ACROSSCHAR(start_match < end_subject, *start_match,
+ start_match++);
#endif
}
else break;
@@ -6014,7 +6831,7 @@
/* The following two optimizations are disabled for partial matching or if
disabling is explicitly requested. */
- if ((options & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial)
+ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial)
{
/* If the pattern was studied, a minimum subject length may be set. This is
a lower bound; no actual string of that length may actually match the
@@ -6028,8 +6845,8 @@
break;
}
- /* If req_byte is set, we know that that character must appear in the
- subject for the match to succeed. If the first character is set, req_byte
+ /* If req_char is set, we know that that character must appear in the
+ subject for the match to succeed. If the first character is set, req_char
must be later in the subject; otherwise the test starts at the match point.
This optimization can save a huge amount of backtracking in patterns with
nested unlimited repeats that aren't going to match. Writing separate code
@@ -6042,28 +6859,28 @@
32-megabyte string... so we don't do this when the string is sufficiently
long. */
- if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX)
+ if (has_req_char && end_subject - start_match < REQ_BYTE_MAX)
{
- register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);
+ register PCRE_PUCHAR p = start_match + (has_first_char? 1:0);
/* We don't need to repeat the search if we haven't yet reached the
place we found it at last time. */
- if (p > req_byte_ptr)
+ if (p > req_char_ptr)
{
- if (req_byte_caseless)
+ if (req_char != req_char2)
{
while (p < end_subject)
{
register int pp = *p++;
- if (pp == req_byte || pp == req_byte2) { p--; break; }
+ if (pp == req_char || pp == req_char2) { p--; break; }
}
}
else
{
while (p < end_subject)
{
- if (*p++ == req_byte) { p--; break; }
+ if (*p++ == req_char) { p--; break; }
}
}
@@ -6080,7 +6897,7 @@
found it, so that we don't search again next time round the loop if
the start hasn't passed this character yet. */
- req_byte_ptr = p;
+ req_char_ptr = p;
}
}
}
@@ -6097,12 +6914,25 @@
md->start_match_ptr = start_match;
md->start_used_ptr = start_match;
md->match_call_count = 0;
- rc = match(start_match, md->start_code, start_match, NULL, 2, md, ims, NULL,
- 0, 0);
+ md->match_function_type = 0;
+ md->end_offset_top = 0;
+ rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0);
if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr;
switch(rc)
{
+ /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
+ the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP
+ entirely. The only way we can do that is to re-do the match at the same
+ point, with a flag to force SKIP with an argument to be ignored. Just
+ treating this case as NOMATCH does not work because it does not check other
+ alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */
+
+ case MATCH_SKIP_ARG:
+ new_start_match = start_match;
+ md->ignore_skip_arg = TRUE;
+ break;
+
/* SKIP passes back the next starting point explicitly, but if it is the
same as the match we have just done, treat it as NOMATCH. */
@@ -6114,23 +6944,18 @@
}
/* Fall through */
- /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
- the SKIP's arg was not found. We also treat this as NOMATCH. */
-
- case MATCH_SKIP_ARG:
- /* Fall through */
-
/* NOMATCH and PRUNE advance by one character. THEN at this level acts
- exactly like PRUNE. */
+ exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */
case MATCH_NOMATCH:
case MATCH_PRUNE:
case MATCH_THEN:
+ md->ignore_skip_arg = FALSE;
new_start_match = start_match + 1;
-#ifdef SUPPORT_UTF8
- if (utf8)
- while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80)
- new_start_match++;
+#ifdef SUPPORT_UTF
+ if (utf)
+ ACROSSCHAR(new_start_match < end_subject, *new_start_match,
+ new_start_match++);
#endif
break;
@@ -6168,9 +6993,13 @@
/* If we have just passed a CR and we are now at a LF, and the pattern does
not contain any explicit matches for \r or \n, and the newline option is CRLF
- or ANY or ANYCRLF, advance the match position by one more character. */
+ or ANY or ANYCRLF, advance the match position by one more character. In
+ normal matching start_match will aways be greater than the first position at
+ this stage, but a failed *SKIP can cause a return at the same point, which is
+ why the first test exists. */
- if (start_match[-1] == CHAR_CR &&
+ if (start_match > (PCRE_PUCHAR)subject + start_offset &&
+ start_match[-1] == CHAR_CR &&
start_match < end_subject &&
*start_match == CHAR_NL &&
(re->flags & PCRE_HASCRORLF) == 0 &&
@@ -6208,21 +7037,41 @@
{
if (using_temporary_offsets)
{
- if (offsetcount >= 4)
+ if (arg_offset_max >= 4)
{
memcpy(offsets + 2, md->offset_vector + 2,
- (offsetcount - 2) * sizeof(int));
+ (arg_offset_max - 2) * sizeof(int));
DPRINTF(("Copied offsets from temporary memory\n"));
}
- if (md->end_offset_top > offsetcount) md->offset_overflow = TRUE;
+ if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;
DPRINTF(("Freeing temporary memory\n"));
- (pcre_free)(md->offset_vector);
+ (PUBL(free))(md->offset_vector);
}
- /* Set the return code to the number of captured strings, or 0 if there are
+ /* Set the return code to the number of captured strings, or 0 if there were
too many to fit into the vector. */
- rc = md->offset_overflow? 0 : md->end_offset_top/2;
+ rc = (md->offset_overflow && md->end_offset_top >= arg_offset_max)?
+ 0 : md->end_offset_top/2;
+
+ /* If there is space in the offset vector, set any unused pairs at the end of
+ the pattern to -1 for backwards compatibility. It is documented that this
+ happens. In earlier versions, the whole set of potential capturing offsets
+ was set to -1 each time round the loop, but this is handled differently now.
+ "Gaps" are set to -1 dynamically instead (this fixes a bug). Thus, it is only
+ those at the end that need unsetting here. We can't just unset them all at
+ the start of the whole thing because they may get set in one branch that is
+ not the final matching branch. */
+
+ if (md->end_offset_top/2 <= re->top_bracket && offsets != NULL)
+ {
+ register int *iptr, *iend;
+ int resetcount = 2 + re->top_bracket * 2;
+ if (resetcount > offsetcount) resetcount = offsetcount;
+ iptr = offsets + md->end_offset_top;
+ iend = offsets + resetcount;
+ while (iptr < iend) *iptr++ = -1;
+ }
/* If there is space, set up the whole thing as substring 0. The value of
md->start_match_ptr might be modified if \K was encountered on the success
@@ -6234,8 +7083,15 @@
offsets[1] = (int)(md->end_match_ptr - md->start_subject);
}
+ /* Return MARK data if requested */
+
+ if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
+ *(extra_data->mark) = (pcre_uchar *)md->mark;
DPRINTF((">>>> returning %d\n", rc));
- goto RETURN_MARK;
+#ifdef NO_RECURSE
+ release_match_heapframes(&frame_zero);
+#endif
+ return rc;
}
/* Control gets here if there has been an error, or if the overall match
@@ -6244,7 +7100,7 @@
if (using_temporary_offsets)
{
DPRINTF(("Freeing temporary memory\n"));
- (pcre_free)(md->offset_vector);
+ (PUBL(free))(md->offset_vector);
}
/* For anything other than nomatch or partial match, just return the code. */
@@ -6252,6 +7108,9 @@
if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
{
DPRINTF((">>>> error: returning %d\n", rc));
+#ifdef NO_RECURSE
+ release_match_heapframes(&frame_zero);
+#endif
return rc;
}
@@ -6263,8 +7122,8 @@
md->mark = NULL;
if (offsetcount > 1)
{
- offsets[0] = (int)(start_partial - (USPTR)subject);
- offsets[1] = (int)(end_subject - (USPTR)subject);
+ offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
+ offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
}
rc = PCRE_ERROR_PARTIAL;
}
@@ -6279,10 +7138,11 @@
/* Return the MARK data if it has been requested. */
-RETURN_MARK:
-
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
- *(extra_data->mark) = (unsigned char *)(md->mark);
+ *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
+#ifdef NO_RECURSE
+ release_match_heapframes(&frame_zero);
+#endif
return rc;
}
diff -Nru pcre3-8.12/pcre_fullinfo.c pcre3-8.31/pcre_fullinfo.c
--- pcre3-8.12/pcre_fullinfo.c 2009-10-05 10:40:30.000000000 +0000
+++ pcre3-8.31/pcre_fullinfo.c 2012-06-02 10:55:16.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2009 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -65,13 +65,17 @@
Returns: 0 if data returned, negative on error
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what,
- void *where)
+pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data,
+ int what, void *where)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data,
+ int what, void *where)
+#endif
{
-real_pcre internal_re;
-pcre_study_data internal_study;
-const real_pcre *re = (const real_pcre *)argument_re;
+const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
const pcre_study_data *study = NULL;
if (re == NULL || where == NULL) return PCRE_ERROR_NULL;
@@ -79,12 +83,18 @@
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
study = (const pcre_study_data *)extra_data->study_data;
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
+REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
+means that the pattern is likely compiled with different endianness. */
+
if (re->magic_number != MAGIC_NUMBER)
- {
- re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
- if (re == NULL) return PCRE_ERROR_BADMAGIC;
- if (study != NULL) study = &internal_study;
- }
+ return re->magic_number == REVERSED_MAGIC_NUMBER?
+ PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
+
+/* Check that this pattern was compiled in the correct bit mode */
+
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
switch (what)
{
@@ -100,6 +110,18 @@
*((size_t *)where) = (study == NULL)? 0 : study->size;
break;
+ case PCRE_INFO_JITSIZE:
+#ifdef SUPPORT_JIT
+ *((size_t *)where) =
+ (extra_data != NULL &&
+ (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra_data->executable_jit != NULL)?
+ PRIV(jit_get_size)(extra_data->executable_jit) : 0;
+#else
+ *((size_t *)where) = 0;
+#endif
+ break;
+
case PCRE_INFO_CAPTURECOUNT:
*((int *)where) = re->top_bracket;
break;
@@ -110,7 +132,7 @@
case PCRE_INFO_FIRSTBYTE:
*((int *)where) =
- ((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte :
+ ((re->flags & PCRE_FIRSTSET) != 0)? re->first_char :
((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
break;
@@ -118,7 +140,7 @@
block, not the internal copy (with flipped integer fields). */
case PCRE_INFO_FIRSTTABLE:
- *((const uschar **)where) =
+ *((const pcre_uint8 **)where) =
(study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)?
((const pcre_study_data *)extra_data->study_data)->start_bits : NULL;
break;
@@ -126,12 +148,18 @@
case PCRE_INFO_MINLENGTH:
*((int *)where) =
(study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)?
- study->minlength : -1;
+ (int)(study->minlength) : -1;
+ break;
+
+ case PCRE_INFO_JIT:
+ *((int *)where) = extra_data != NULL &&
+ (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra_data->executable_jit != NULL;
break;
case PCRE_INFO_LASTLITERAL:
*((int *)where) =
- ((re->flags & PCRE_REQCHSET) != 0)? re->req_byte : -1;
+ ((re->flags & PCRE_REQCHSET) != 0)? re->req_char : -1;
break;
case PCRE_INFO_NAMEENTRYSIZE:
@@ -143,11 +171,11 @@
break;
case PCRE_INFO_NAMETABLE:
- *((const uschar **)where) = (const uschar *)re + re->name_table_offset;
+ *((const pcre_uchar **)where) = (const pcre_uchar *)re + re->name_table_offset;
break;
case PCRE_INFO_DEFAULT_TABLES:
- *((const uschar **)where) = (const uschar *)(_pcre_default_tables);
+ *((const pcre_uint8 **)where) = (const pcre_uint8 *)(PRIV(default_tables));
break;
/* From release 8.00 this will always return TRUE because NOPARTIAL is
@@ -165,6 +193,10 @@
*((int *)where) = (re->flags & PCRE_HASCRORLF) != 0;
break;
+ case PCRE_INFO_MAXLOOKBEHIND:
+ *((int *)where) = re->max_lookbehind;
+ break;
+
default: return PCRE_ERROR_BADOPTION;
}
diff -Nru pcre3-8.12/pcre_get.c pcre3-8.31/pcre_get.c
--- pcre3-8.12/pcre_get.c 2008-07-09 15:58:24.000000000 +0000
+++ pcre3-8.31/pcre_get.c 2012-01-17 14:10:47.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -65,14 +65,20 @@
(PCRE_ERROR_NOSUBSTRING) if not found
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_stringnumber(const pcre *code, const char *stringname)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname)
+#endif
{
int rc;
int entrysize;
int top, bot;
-uschar *nametable;
+pcre_uchar *nametable;
+#ifdef COMPILE_PCRE8
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
return rc;
if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
@@ -81,14 +87,26 @@
return rc;
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
return rc;
+#endif
+#ifdef COMPILE_PCRE16
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+ return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+ return rc;
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+ return rc;
+#endif
bot = 0;
while (top > bot)
{
int mid = (top + bot) / 2;
- uschar *entry = nametable + entrysize*mid;
- int c = strcmp(stringname, (char *)(entry + 2));
- if (c == 0) return (entry[0] << 8) + entry[1];
+ pcre_uchar *entry = nametable + entrysize*mid;
+ int c = STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(entry + IMM2_SIZE));
+ if (c == 0) return GET2(entry, 0);
if (c > 0) bot = mid + 1; else top = mid;
}
@@ -114,15 +132,22 @@
(PCRE_ERROR_NOSUBSTRING) if not found
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_stringtable_entries(const pcre *code, const char *stringname,
char **firstptr, char **lastptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname,
+ PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr)
+#endif
{
int rc;
int entrysize;
int top, bot;
-uschar *nametable, *lastentry;
+pcre_uchar *nametable, *lastentry;
+#ifdef COMPILE_PCRE8
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
return rc;
if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
@@ -131,30 +156,49 @@
return rc;
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
return rc;
+#endif
+#ifdef COMPILE_PCRE16
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+ return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+ return rc;
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+ return rc;
+#endif
lastentry = nametable + entrysize * (top - 1);
bot = 0;
while (top > bot)
{
int mid = (top + bot) / 2;
- uschar *entry = nametable + entrysize*mid;
- int c = strcmp(stringname, (char *)(entry + 2));
+ pcre_uchar *entry = nametable + entrysize*mid;
+ int c = STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(entry + IMM2_SIZE));
if (c == 0)
{
- uschar *first = entry;
- uschar *last = entry;
+ pcre_uchar *first = entry;
+ pcre_uchar *last = entry;
while (first > nametable)
{
- if (strcmp(stringname, (char *)(first - entrysize + 2)) != 0) break;
+ if (STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(first - entrysize + IMM2_SIZE)) != 0) break;
first -= entrysize;
}
while (last < lastentry)
{
- if (strcmp(stringname, (char *)(last + entrysize + 2)) != 0) break;
+ if (STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break;
last += entrysize;
}
+#ifdef COMPILE_PCRE8
*firstptr = (char *)first;
*lastptr = (char *)last;
+#else
+ *firstptr = (PCRE_UCHAR16 *)first;
+ *lastptr = (PCRE_UCHAR16 *)last;
+#endif
return entrysize;
}
if (c > 0) bot = mid + 1; else top = mid;
@@ -182,23 +226,39 @@
or a negative number on error
*/
+#ifdef COMPILE_PCRE8
static int
get_first_set(const pcre *code, const char *stringname, int *ovector)
+#else
+static int
+get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector)
+#endif
{
-const real_pcre *re = (const real_pcre *)code;
+const REAL_PCRE *re = (const REAL_PCRE *)code;
int entrysize;
+pcre_uchar *entry;
+#ifdef COMPILE_PCRE8
char *first, *last;
-uschar *entry;
+#else
+PCRE_UCHAR16 *first, *last;
+#endif
+
+#ifdef COMPILE_PCRE8
if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
return pcre_get_stringnumber(code, stringname);
entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
+#else
+if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
+ return pcre16_get_stringnumber(code, stringname);
+entrysize = pcre16_get_stringtable_entries(code, stringname, &first, &last);
+#endif
if (entrysize <= 0) return entrysize;
-for (entry = (uschar *)first; entry <= (uschar *)last; entry += entrysize)
+for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize)
{
- int n = (entry[0] << 8) + entry[1];
+ int n = GET2(entry, 0);
if (ovector[n*2] >= 0) return n;
}
-return (first[0] << 8) + first[1];
+return GET2(entry, 0);
}
@@ -231,9 +291,15 @@
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_copy_substring(const char *subject, int *ovector, int stringcount,
int stringnumber, char *buffer, int size)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
+ int stringnumber, PCRE_UCHAR16 *buffer, int size)
+#endif
{
int yield;
if (stringnumber < 0 || stringnumber >= stringcount)
@@ -241,7 +307,7 @@
stringnumber *= 2;
yield = ovector[stringnumber+1] - ovector[stringnumber];
if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
-memcpy(buffer, subject + ovector[stringnumber], yield);
+memcpy(buffer, subject + ovector[stringnumber], IN_UCHARS(yield));
buffer[yield] = 0;
return yield;
}
@@ -276,13 +342,25 @@
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
*/
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_copy_named_substring(const pcre *code, const char *subject,
+ int *ovector, int stringcount, const char *stringname,
+ char *buffer, int size)
+#else
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector,
- int stringcount, const char *stringname, char *buffer, int size)
+pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
+ int *ovector, int stringcount, PCRE_SPTR16 stringname,
+ PCRE_UCHAR16 *buffer, int size)
+#endif
{
int n = get_first_set(code, stringname, ovector);
if (n <= 0) return n;
+#ifdef COMPILE_PCRE8
return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
+#else
+return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size);
+#endif
}
@@ -308,29 +386,39 @@
PCRE_ERROR_NOMEMORY (-6) failed to get store
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
const char ***listptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount,
+ PCRE_SPTR16 **listptr)
+#endif
{
int i;
-int size = sizeof(char *);
+int size = sizeof(pcre_uchar *);
int double_count = stringcount * 2;
-char **stringlist;
-char *p;
+pcre_uchar **stringlist;
+pcre_uchar *p;
for (i = 0; i < double_count; i += 2)
- size += sizeof(char *) + ovector[i+1] - ovector[i] + 1;
+ size += sizeof(pcre_uchar *) + IN_UCHARS(ovector[i+1] - ovector[i] + 1);
-stringlist = (char **)(pcre_malloc)(size);
+stringlist = (pcre_uchar **)(PUBL(malloc))(size);
if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
+#ifdef COMPILE_PCRE8
*listptr = (const char **)stringlist;
-p = (char *)(stringlist + stringcount + 1);
+#else
+*listptr = (PCRE_SPTR16 *)stringlist;
+#endif
+p = (pcre_uchar *)(stringlist + stringcount + 1);
for (i = 0; i < double_count; i += 2)
{
int len = ovector[i+1] - ovector[i];
- memcpy(p, subject + ovector[i], len);
+ memcpy(p, subject + ovector[i], IN_UCHARS(len));
*stringlist++ = p;
p += len;
*p++ = 0;
@@ -347,16 +435,22 @@
*************************************************/
/* This function exists for the benefit of people calling PCRE from non-C
-programs that can call its functions, but not free() or (pcre_free)() directly.
+programs that can call its functions, but not free() or (PUBL(free))()
+directly.
Argument: the result of a previous pcre_get_substring_list()
Returns: nothing
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
pcre_free_substring_list(const char **pointer)
+#else
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre16_free_substring_list(PCRE_SPTR16 *pointer)
+#endif
{
-(pcre_free)((void *)pointer);
+(PUBL(free))((void *)pointer);
}
@@ -386,21 +480,31 @@
PCRE_ERROR_NOSUBSTRING (-7) substring not present
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_substring(const char *subject, int *ovector, int stringcount,
int stringnumber, const char **stringptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
+ int stringnumber, PCRE_SPTR16 *stringptr)
+#endif
{
int yield;
-char *substring;
+pcre_uchar *substring;
if (stringnumber < 0 || stringnumber >= stringcount)
return PCRE_ERROR_NOSUBSTRING;
stringnumber *= 2;
yield = ovector[stringnumber+1] - ovector[stringnumber];
-substring = (char *)(pcre_malloc)(yield + 1);
+substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1));
if (substring == NULL) return PCRE_ERROR_NOMEMORY;
-memcpy(substring, subject + ovector[stringnumber], yield);
+memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield));
substring[yield] = 0;
-*stringptr = substring;
+#ifdef COMPILE_PCRE8
+*stringptr = (const char *)substring;
+#else
+*stringptr = (PCRE_SPTR16)substring;
+#endif
return yield;
}
@@ -433,13 +537,25 @@
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_get_named_substring(const pcre *code, const char *subject, int *ovector,
- int stringcount, const char *stringname, const char **stringptr)
+pcre_get_named_substring(const pcre *code, const char *subject,
+ int *ovector, int stringcount, const char *stringname,
+ const char **stringptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
+ int *ovector, int stringcount, PCRE_SPTR16 stringname,
+ PCRE_SPTR16 *stringptr)
+#endif
{
int n = get_first_set(code, stringname, ovector);
if (n <= 0) return n;
+#ifdef COMPILE_PCRE8
return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
+#else
+return pcre16_get_substring(subject, ovector, stringcount, n, stringptr);
+#endif
}
@@ -450,16 +566,22 @@
*************************************************/
/* This function exists for the benefit of people calling PCRE from non-C
-programs that can call its functions, but not free() or (pcre_free)() directly.
+programs that can call its functions, but not free() or (PUBL(free))()
+directly.
Argument: the result of a previous pcre_get_substring()
Returns: nothing
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
pcre_free_substring(const char *pointer)
+#else
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre16_free_substring(PCRE_SPTR16 pointer)
+#endif
{
-(pcre_free)((void *)pointer);
+(PUBL(free))((void *)pointer);
}
/* End of pcre_get.c */
diff -Nru pcre3-8.12/pcre_globals.c pcre3-8.31/pcre_globals.c
--- pcre3-8.12/pcre_globals.c 2010-03-10 16:05:24.000000000 +0000
+++ pcre3-8.31/pcre_globals.c 2012-01-05 17:07:07.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -67,18 +67,18 @@
{
free(aPtr);
}
-PCRE_EXP_DATA_DEFN void *(*pcre_malloc)(size_t) = LocalPcreMalloc;
-PCRE_EXP_DATA_DEFN void (*pcre_free)(void *) = LocalPcreFree;
-PCRE_EXP_DATA_DEFN void *(*pcre_stack_malloc)(size_t) = LocalPcreMalloc;
-PCRE_EXP_DATA_DEFN void (*pcre_stack_free)(void *) = LocalPcreFree;
-PCRE_EXP_DATA_DEFN int (*pcre_callout)(pcre_callout_block *) = NULL;
+PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = LocalPcreMalloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = LocalPcreFree;
+PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = LocalPcreMalloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = LocalPcreFree;
+PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
#elif !defined VPCOMPAT
-PCRE_EXP_DATA_DEFN void *(*pcre_malloc)(size_t) = malloc;
-PCRE_EXP_DATA_DEFN void (*pcre_free)(void *) = free;
-PCRE_EXP_DATA_DEFN void *(*pcre_stack_malloc)(size_t) = malloc;
-PCRE_EXP_DATA_DEFN void (*pcre_stack_free)(void *) = free;
-PCRE_EXP_DATA_DEFN int (*pcre_callout)(pcre_callout_block *) = NULL;
+PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = malloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = free;
+PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = malloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = free;
+PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
#endif
/* End of pcre_globals.c */
diff -Nru pcre3-8.12/pcre_info.c pcre3-8.31/pcre_info.c
--- pcre3-8.12/pcre_info.c 2009-03-15 16:56:56.000000000 +0000
+++ pcre3-8.31/pcre_info.c 1970-01-01 00:00:00.000000000 +0000
@@ -1,93 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2009 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_info(), which gives some
-information about a compiled pattern. However, use of this function is now
-deprecated, as it has been superseded by pcre_fullinfo(). */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* (Obsolete) Return info about compiled pattern *
-*************************************************/
-
-/* This is the original "info" function. It picks potentially useful data out
-of the private structure, but its interface was too rigid. It remains for
-backwards compatibility. The public options are passed back in an int - though
-the re->options field has been expanded to a long int, all the public options
-at the low end of it, and so even on 16-bit systems this will still be OK.
-Therefore, I haven't changed the API for pcre_info().
-
-Arguments:
- argument_re points to compiled code
- optptr where to pass back the options
- first_byte where to pass back the first character,
- or -1 if multiline and all branches start ^,
- or -2 otherwise
-
-Returns: number of capturing subpatterns
- or negative values on error
-*/
-
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_info(const pcre *argument_re, int *optptr, int *first_byte)
-{
-real_pcre internal_re;
-const real_pcre *re = (const real_pcre *)argument_re;
-if (re == NULL) return PCRE_ERROR_NULL;
-if (re->magic_number != MAGIC_NUMBER)
- {
- re = _pcre_try_flipped(re, &internal_re, NULL, NULL);
- if (re == NULL) return PCRE_ERROR_BADMAGIC;
- }
-if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_COMPILE_OPTIONS);
-if (first_byte != NULL)
- *first_byte = ((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte :
- ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
-return re->top_bracket;
-}
-
-/* End of pcre_info.c */
diff -Nru pcre3-8.12/pcre_internal.h pcre3-8.31/pcre_internal.h
--- pcre3-8.12/pcre_internal.h 2010-11-24 17:38:32.000000000 +0000
+++ pcre3-8.31/pcre_internal.h 2012-06-17 16:06:48.000000000 +0000
@@ -7,7 +7,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2010 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,8 @@
/* This header contains definitions that are shared between the different
modules, but which are not relevant to the exported API. This includes some
-functions whose names all begin with "_pcre_". */
+functions whose names all begin with "_pcre_" or "_pcre16_" depending on
+the PRIV macro. */
#ifndef PCRE_INTERNAL_H
#define PCRE_INTERNAL_H
@@ -51,20 +52,39 @@
#define PCRE_DEBUG
#endif
-/* We do not support both EBCDIC and UTF-8 at the same time. The "configure"
-script prevents both being selected, but not everybody uses "configure". */
-
-#if defined EBCDIC && defined SUPPORT_UTF8
-#error The use of both EBCDIC and SUPPORT_UTF8 is not supported.
+/* PCRE is compiled as an 8 bit library if it is not requested otherwise. */
+#ifndef COMPILE_PCRE16
+#define COMPILE_PCRE8
#endif
-/* If SUPPORT_UCP is defined, SUPPORT_UTF8 must also be defined. The
+/* If SUPPORT_UCP is defined, SUPPORT_UTF must also be defined. The
"configure" script ensures this, but not everybody uses "configure". */
-#if defined SUPPORT_UCP && !defined SUPPORT_UTF8
+#if defined SUPPORT_UCP && !(defined SUPPORT_UTF)
+#define SUPPORT_UTF 1
+#endif
+
+/* We define SUPPORT_UTF if SUPPORT_UTF8 is enabled for compatibility
+reasons with existing code. */
+
+#if defined SUPPORT_UTF8 && !(defined SUPPORT_UTF)
+#define SUPPORT_UTF 1
+#endif
+
+/* Fixme: SUPPORT_UTF8 should be eventually disappear from the code.
+Until then we define it if SUPPORT_UTF is defined. */
+
+#if defined SUPPORT_UTF && !(defined SUPPORT_UTF8)
#define SUPPORT_UTF8 1
#endif
+/* We do not support both EBCDIC and UTF-8/16 at the same time. The "configure"
+script prevents both being selected, but not everybody uses "configure". */
+
+#if defined EBCDIC && defined SUPPORT_UTF
+#error The use of both EBCDIC and SUPPORT_UTF8/16 is not supported.
+#endif
+
/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
inline, and there are *still* stupid compilers about that don't like indented
pre-processor statements, or at least there were when I first wrote this. After
@@ -158,12 +178,14 @@
#define PCRE_CALL_CONVENTION
#endif
-/* We need to have types that specify unsigned 16-bit and 32-bit integers. We
+/* We need to have types that specify unsigned 8, 16 and 32-bit integers. We
cannot determine these outside the compilation (e.g. by running a program as
part of "configure") because PCRE is often cross-compiled for use on other
systems. Instead we make use of the maximum sizes that are available at
preprocessor time in standard C environments. */
+typedef unsigned char pcre_uint8;
+
#if USHRT_MAX == 65535
typedef unsigned short pcre_uint16;
typedef short pcre_int16;
@@ -206,12 +228,47 @@
/* All character handling must be done as unsigned characters. Otherwise there
are problems with top-bit-set characters and functions such as isspace().
-However, we leave the interface to the outside world as char *, because that
-should make things easier for callers. We define a short type for unsigned char
-to save lots of typing. I tried "uchar", but it causes problems on Digital
-Unix, where it is defined in sys/types, so use "uschar" instead. */
+However, we leave the interface to the outside world as char * or short *,
+because that should make things easier for callers. This character type is
+called pcre_uchar.
+
+The IN_UCHARS macro multiply its argument with the byte size of the current
+pcre_uchar type. Useful for memcpy and such operations, whose require the
+byte size of their input/output buffers.
+
+The MAX_255 macro checks whether its pcre_uchar input is less than 256.
+
+The TABLE_GET macro is designed for accessing elements of tables whose contain
+exactly 256 items. When the character is able to contain more than 256
+items, some check is needed before accessing these tables.
+*/
+
+#ifdef COMPILE_PCRE8
+
+typedef unsigned char pcre_uchar;
+#define IN_UCHARS(x) (x)
+#define MAX_255(c) 1
+#define TABLE_GET(c, table, default) ((table)[c])
+
+#else
+
+#ifdef COMPILE_PCRE16
+#if USHRT_MAX != 65535
+/* This is a warning message. Change PCRE_UCHAR16 to a 16 bit data type in
+pcre.h(.in) and disable (comment out) this message. */
+#error Warning: PCRE_UCHAR16 is not a 16 bit data type.
+#endif
+
+typedef pcre_uint16 pcre_uchar;
+#define IN_UCHARS(x) ((x) << 1)
+#define MAX_255(c) ((c) <= 255u)
+#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))
-typedef unsigned char uschar;
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
/* This is an unsigned int value that no character can ever have. UTF-8
characters only go up to 0x7fffffff (though Unicode doesn't go beyond
@@ -234,8 +291,8 @@
#define IS_NEWLINE(p) \
((NLBLOCK->nltype != NLTYPE_FIXED)? \
((p) < NLBLOCK->PSEND && \
- _pcre_is_newline((p), NLBLOCK->nltype, NLBLOCK->PSEND, &(NLBLOCK->nllen),\
- utf8)) \
+ PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \
+ &(NLBLOCK->nllen), utf)) \
: \
((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \
(p)[0] == NLBLOCK->nl[0] && \
@@ -248,8 +305,8 @@
#define WAS_NEWLINE(p) \
((NLBLOCK->nltype != NLTYPE_FIXED)? \
((p) > NLBLOCK->PSSTART && \
- _pcre_was_newline((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \
- &(NLBLOCK->nllen), utf8)) \
+ PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \
+ &(NLBLOCK->nllen), utf)) \
: \
((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \
(p)[-NLBLOCK->nllen] == NLBLOCK->nl[0] && \
@@ -267,15 +324,11 @@
must begin with PCRE_. */
#ifdef CUSTOM_SUBJECT_PTR
-#define PCRE_SPTR CUSTOM_SUBJECT_PTR
-#define USPTR CUSTOM_SUBJECT_PTR
+#define PCRE_PUCHAR CUSTOM_SUBJECT_PTR
#else
-#define PCRE_SPTR const char *
-#define USPTR const unsigned char *
+#define PCRE_PUCHAR const pcre_uchar *
#endif
-
-
/* Include the public PCRE header and the definitions of UCP character property
values. */
@@ -343,6 +396,8 @@
the config.h file, but can be overridden by using -D on the command line. This
is automated on Unix systems via the "configure" command. */
+#ifdef COMPILE_PCRE8
+
#if LINK_SIZE == 2
#define PUT(a,n,d) \
@@ -379,13 +434,54 @@
#define GET(a,n) \
(((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
-#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
+/* Keep it positive */
+#define MAX_PATTERN_SIZE (1 << 30)
+
+#else
+#error LINK_SIZE must be either 2, 3, or 4
+#endif
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+
+#if LINK_SIZE == 2
+
+#undef LINK_SIZE
+#define LINK_SIZE 1
+
+#define PUT(a,n,d) \
+ (a[n] = (d))
+
+#define GET(a,n) \
+ (a[n])
+
+#define MAX_PATTERN_SIZE (1 << 16)
+
+#elif LINK_SIZE == 3 || LINK_SIZE == 4
+#undef LINK_SIZE
+#define LINK_SIZE 2
+
+#define PUT(a,n,d) \
+ (a[n] = (d) >> 16), \
+ (a[(n)+1] = (d) & 65535)
+
+#define GET(a,n) \
+ (((a)[n] << 16) | (a)[(n)+1])
+
+/* Keep it positive */
+#define MAX_PATTERN_SIZE (1 << 30)
#else
#error LINK_SIZE must be either 2, 3, or 4
#endif
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
/* Convenience macro defined in terms of the others */
@@ -396,6 +492,10 @@
offsets changes. There are used for repeat counts and for other things such as
capturing parenthesis numbers in back references. */
+#ifdef COMPILE_PCRE8
+
+#define IMM2_SIZE 2
+
#define PUT2(a,n,d) \
a[n] = (d) >> 8; \
a[(n)+1] = (d) & 255
@@ -403,17 +503,44 @@
#define GET2(a,n) \
(((a)[n] << 8) | (a)[(n)+1])
-#define PUT2INC(a,n,d) PUT2(a,n,d), a += 2
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+
+#define IMM2_SIZE 1
+
+#define PUT2(a,n,d) \
+ a[n] = d
+
+#define GET2(a,n) \
+ a[n]
+
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+
+#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE
+
+/* The maximum length of a MARK name is currently one data unit; it may be
+changed in future to be a fixed number of bytes or to depend on LINK_SIZE. */
+
+#define MAX_MARK ((1 << (sizeof(pcre_uchar)*8)) - 1)
+/* When UTF encoding is being used, a character is no longer just a single
+character. The macros for character handling generate simple sequences when
+used in character-mode, and more complicated ones for UTF characters.
+GETCHARLENTEST and other macros are not used when UTF is not supported,
+so they are not defined. To make sure they can never even appear when
+UTF support is omitted, we don't even define them. */
-/* When UTF-8 encoding is being used, a character is no longer just a single
-byte. The macros for character handling generate simple sequences when used in
-byte-mode, and more complicated ones for UTF-8 characters. GETCHARLENTEST is
-not used when UTF-8 is not supported, so it is not defined, and BACKCHAR should
-never be called in byte mode. To make sure they can never even appear when
-UTF-8 support is omitted, we don't even define them. */
+#ifndef SUPPORT_UTF
-#ifndef SUPPORT_UTF8
+/* #define MAX_VALUE_FOR_SINGLE_CHAR */
+/* #define HAS_EXTRALEN(c) */
+/* #define GET_EXTRALEN(c) */
+/* #define NOT_FIRSTCHAR(c) */
#define GETCHAR(c, eptr) c = *eptr;
#define GETCHARTEST(c, eptr) c = *eptr;
#define GETCHARINC(c, eptr) c = *eptr++;
@@ -421,14 +548,36 @@
#define GETCHARLEN(c, eptr, len) c = *eptr;
/* #define GETCHARLENTEST(c, eptr, len) */
/* #define BACKCHAR(eptr) */
+/* #define FORWARDCHAR(eptr) */
+/* #define ACROSSCHAR(condition, eptr, action) */
-#else /* SUPPORT_UTF8 */
+#else /* SUPPORT_UTF */
+
+#ifdef COMPILE_PCRE8
/* These macros were originally written in the form of loops that used data
-from the tables whose names start with _pcre_utf8_table. They were rewritten by
+from the tables whose names start with PRIV(utf8_table). They were rewritten by
a user so as not to use loops, because in some environments this gives a
significant performance advantage, and it seems never to do any harm. */
+/* Tells the biggest code point which can be encoded as a single character. */
+
+#define MAX_VALUE_FOR_SINGLE_CHAR 127
+
+/* Tests whether the code point needs extra characters to decode. */
+
+#define HAS_EXTRALEN(c) ((c) >= 0xc0)
+
+/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
+Otherwise it has an undefined behaviour. */
+
+#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f])
+
+/* Returns TRUE, if the given character is not the first character
+of a UTF sequence. */
+
+#define NOT_FIRSTCHAR(c) (((c) & 0xc0) == 0x80)
+
/* Base macro to pick up the remaining bytes of a UTF-8 character, not
advancing the pointer. */
@@ -463,7 +612,7 @@
#define GETCHARTEST(c, eptr) \
c = *eptr; \
- if (utf8 && c >= 0xc0) GETUTF8(c, eptr);
+ if (utf && c >= 0xc0) GETUTF8(c, eptr);
/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing
the pointer. */
@@ -511,7 +660,7 @@
#define GETCHARINCTEST(c, eptr) \
c = *eptr++; \
- if (utf8 && c >= 0xc0) GETUTF8INC(c, eptr);
+ if (utf && c >= 0xc0) GETUTF8INC(c, eptr);
/* Base macro to pick up the remaining bytes of a UTF-8 character, not
advancing the pointer, incrementing the length. */
@@ -563,7 +712,7 @@
#define GETCHARLENTEST(c, eptr, len) \
c = *eptr; \
- if (utf8 && c >= 0xc0) GETUTF8LEN(c, eptr, len);
+ if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len);
/* If the pointer is not at the start of a character, move it back until
it is. This is called only in UTF-8 mode - we don't put a test within the macro
@@ -571,7 +720,116 @@
#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--
-#endif /* SUPPORT_UTF8 */
+/* Same as above, just in the other direction. */
+#define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++
+
+/* Same as above, but it allows a fully customizable form. */
+#define ACROSSCHAR(condition, eptr, action) \
+ while((condition) && ((eptr) & 0xc0) == 0x80) action
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+
+/* Tells the biggest code point which can be encoded as a single character. */
+
+#define MAX_VALUE_FOR_SINGLE_CHAR 65535
+
+/* Tests whether the code point needs extra characters to decode. */
+
+#define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800)
+
+/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
+Otherwise it has an undefined behaviour. */
+
+#define GET_EXTRALEN(c) 1
+
+/* Returns TRUE, if the given character is not the first character
+of a UTF sequence. */
+
+#define NOT_FIRSTCHAR(c) (((c) & 0xfc00) == 0xdc00)
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, not
+advancing the pointer. */
+
+#define GETUTF16(c, eptr) \
+ { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; }
+
+/* Get the next UTF-16 character, not advancing the pointer. This is called when
+we know we are in UTF-16 mode. */
+
+#define GETCHAR(c, eptr) \
+ c = *eptr; \
+ if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr);
+
+/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the
+pointer. */
+
+#define GETCHARTEST(c, eptr) \
+ c = *eptr; \
+ if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr);
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, advancing
+the pointer. */
+
+#define GETUTF16INC(c, eptr) \
+ { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; }
+
+/* Get the next UTF-16 character, advancing the pointer. This is called when we
+know we are in UTF-16 mode. */
+
+#define GETCHARINC(c, eptr) \
+ c = *eptr++; \
+ if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);
+
+/* Get the next character, testing for UTF-16 mode, and advancing the pointer.
+This is called when we don't know if we are in UTF-16 mode. */
+
+#define GETCHARINCTEST(c, eptr) \
+ c = *eptr++; \
+ if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, not
+advancing the pointer, incrementing the length. */
+
+#define GETUTF16LEN(c, eptr, len) \
+ { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; }
+
+/* Get the next UTF-16 character, not advancing the pointer, incrementing
+length if there is a low surrogate. This is called when we know we are in
+UTF-16 mode. */
+
+#define GETCHARLEN(c, eptr, len) \
+ c = *eptr; \
+ if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);
+
+/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the
+pointer, incrementing length if there is a low surrogate. This is called when
+we do not know if we are in UTF-16 mode. */
+
+#define GETCHARLENTEST(c, eptr, len) \
+ c = *eptr; \
+ if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);
+
+/* If the pointer is not at the start of a character, move it back until
+it is. This is called only in UTF-16 mode - we don't put a test within the
+macro because almost all calls are already within a block of UTF-16 only
+code. */
+
+#define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr--
+
+/* Same as above, just in the other direction. */
+#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++
+
+/* Same as above, but it allows a fully customizable form. */
+#define ACROSSCHAR(condition, eptr, action) \
+ if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action
+
+#endif
+
+#endif /* COMPILE_PCRE8 */
+
+#endif /* SUPPORT_UTF */
/* In case there is no definition of offsetof() provided - though any proper
@@ -582,27 +840,32 @@
#endif
-/* These are the public options that can change during matching. */
-
-#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)
-
/* Private flags containing information about the compiled regex. They used to
live at the top end of the options word, but that got almost full, so now they
are in a 16-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as
the restrictions on partial matching have been lifted. It remains for backwards
compatibility. */
-#define PCRE_NOPARTIAL 0x0001 /* can't use partial with this regex */
-#define PCRE_FIRSTSET 0x0002 /* first_byte is set */
-#define PCRE_REQCHSET 0x0004 /* req_byte is set */
-#define PCRE_STARTLINE 0x0008 /* start after \n for multiline */
-#define PCRE_JCHANGED 0x0010 /* j option used in regex */
-#define PCRE_HASCRORLF 0x0020 /* explicit \r or \n in pattern */
+#ifdef COMPILE_PCRE8
+#define PCRE_MODE 0x0001 /* compiled in 8 bit mode */
+#endif
+#ifdef COMPILE_PCRE16
+#define PCRE_MODE 0x0002 /* compiled in 16 bit mode */
+#endif
+#define PCRE_FIRSTSET 0x0010 /* first_char is set */
+#define PCRE_FCH_CASELESS 0x0020 /* caseless first char */
+#define PCRE_REQCHSET 0x0040 /* req_byte is set */
+#define PCRE_RCH_CASELESS 0x0080 /* caseless requested char */
+#define PCRE_STARTLINE 0x0100 /* start after \n for multiline */
+#define PCRE_NOPARTIAL 0x0200 /* can't use partial with this regex */
+#define PCRE_JCHANGED 0x0400 /* j option used in regex */
+#define PCRE_HASCRORLF 0x0800 /* explicit \r or \n in pattern */
+#define PCRE_HASTHEN 0x1000 /* pattern contains (*THEN) */
-/* Options for the "extra" block produced by pcre_study(). */
+/* Flags for the "extra" block produced by pcre_study(). */
-#define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */
-#define PCRE_STUDY_MINLEN 0x02 /* a minimum length field exists */
+#define PCRE_STUDY_MAPPED 0x0001 /* a map of starting chars exists */
+#define PCRE_STUDY_MINLEN 0x0002 /* a minimum length field exists */
/* Masks for identifying the public options that are permitted at compile
time, run time, or study time, respectively. */
@@ -628,13 +891,19 @@
PCRE_DFA_RESTART|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
PCRE_NO_START_OPTIMIZE)
-#define PUBLIC_STUDY_OPTIONS 0 /* None defined */
+#define PUBLIC_STUDY_OPTIONS \
+ (PCRE_STUDY_JIT_COMPILE|PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE| \
+ PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE)
-/* Magic number to provide a small check against being handed junk. Also used
-to detect whether a pattern was compiled on a host of different endianness. */
+/* Magic number to provide a small check against being handed junk. */
#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
+/* This variable is used to detect a loaded regular expression
+in different endianness. */
+
+#define REVERSED_MAGIC_NUMBER 0x45524350UL /* 'ERCP' */
+
/* Negative values for the firstchar and reqchar variables */
#define REQ_UNSET (-2)
@@ -645,12 +914,6 @@
#define REQ_BYTE_MAX 1000
-/* Flags added to firstbyte or reqbyte; a "non-literal" item is either a
-variable-length repeat, or a anything other than literal characters. */
-
-#define REQ_CASELESS 0x0100 /* indicates caselessness */
-#define REQ_VARY 0x0200 /* reqbyte followed non-literal item */
-
/* Miscellaneous definitions. The #ifndef is to pacify compiler warnings in
environments where these macros are defined elsewhere. Unfortunately, there
is no way to do the same for the typedef. */
@@ -679,7 +942,7 @@
application that did need both could compile two versions of the library, using
macros to give the functions distinct names. */
-#ifndef SUPPORT_UTF8
+#ifndef SUPPORT_UTF
/* UTF-8 support is not enabled; use the platform-dependent character literals
so that PCRE works on both ASCII and EBCDIC platforms, in non-UTF-mode only. */
@@ -939,11 +1202,16 @@
#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)"
#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)"
#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)"
-#define STRING_UTF8_RIGHTPAR "UTF8)"
+#ifdef COMPILE_PCRE8
+#define STRING_UTF_RIGHTPAR "UTF8)"
+#endif
+#ifdef COMPILE_PCRE16
+#define STRING_UTF_RIGHTPAR "UTF16)"
+#endif
#define STRING_UCP_RIGHTPAR "UCP)"
#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
-#else /* SUPPORT_UTF8 */
+#else /* SUPPORT_UTF */
/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This
works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode
@@ -1194,11 +1462,16 @@
#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS
-#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
+#ifdef COMPILE_PCRE8
+#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
+#endif
+#ifdef COMPILE_PCRE16
+#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
+#endif
#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS
#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS
-#endif /* SUPPORT_UTF8 */
+#endif /* SUPPORT_UTF */
/* Escape items that are just an encoding of a particular data value. */
@@ -1238,7 +1511,7 @@
#define PT_WORD 8 /* Word - L plus N plus underscore */
/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
-contain UTF-8 characters with values greater than 255. */
+contain characters with values greater than 255. */
#define XCL_NOT 0x01 /* Flag: this is a negative class */
#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
@@ -1254,8 +1527,8 @@
their negation. Also, they must appear in the same order as in the opcode
definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it
corresponds to "." in DOTALL mode rather than an escape sequence. It is also
-used for [^] in JavaScript compatibility mode. In non-DOTALL mode, "." behaves
-like \N.
+used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In
+non-DOTALL mode, "." behaves like \N.
The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc.
when PCRE_UCP is set, when replacement of \d etc by \p sequences is required.
@@ -1299,6 +1572,7 @@
OP_WHITESPACE, /* 9 \s */
OP_NOT_WORDCHAR, /* 10 \W */
OP_WORDCHAR, /* 11 \w */
+
OP_ANY, /* 12 Match any character except newline */
OP_ALLANY, /* 13 Match any character */
OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */
@@ -1313,141 +1587,205 @@
OP_EODN, /* 23 End of data or \n at end of data: \Z. */
OP_EOD, /* 24 End of data: \z */
- OP_OPT, /* 25 Set runtime options */
- OP_CIRC, /* 26 Start of line - varies with multiline switch */
- OP_DOLL, /* 27 End of line - varies with multiline switch */
- OP_CHAR, /* 28 Match one character, casefully */
- OP_CHARNC, /* 29 Match one character, caselessly */
- OP_NOT, /* 30 Match one character, not the following one */
-
- OP_STAR, /* 31 The maximizing and minimizing versions of */
- OP_MINSTAR, /* 32 these six opcodes must come in pairs, with */
- OP_PLUS, /* 33 the minimizing one second. */
- OP_MINPLUS, /* 34 This first set applies to single characters.*/
- OP_QUERY, /* 35 */
- OP_MINQUERY, /* 36 */
-
- OP_UPTO, /* 37 From 0 to n matches */
- OP_MINUPTO, /* 38 */
- OP_EXACT, /* 39 Exactly n matches */
-
- OP_POSSTAR, /* 40 Possessified star */
- OP_POSPLUS, /* 41 Possessified plus */
- OP_POSQUERY, /* 42 Posesssified query */
- OP_POSUPTO, /* 43 Possessified upto */
-
- OP_NOTSTAR, /* 44 The maximizing and minimizing versions of */
- OP_NOTMINSTAR, /* 45 these six opcodes must come in pairs, with */
- OP_NOTPLUS, /* 46 the minimizing one second. They must be in */
- OP_NOTMINPLUS, /* 47 exactly the same order as those above. */
- OP_NOTQUERY, /* 48 This set applies to "not" single characters. */
- OP_NOTMINQUERY, /* 49 */
-
- OP_NOTUPTO, /* 50 From 0 to n matches */
- OP_NOTMINUPTO, /* 51 */
- OP_NOTEXACT, /* 52 Exactly n matches */
-
- OP_NOTPOSSTAR, /* 53 Possessified versions */
- OP_NOTPOSPLUS, /* 54 */
- OP_NOTPOSQUERY, /* 55 */
- OP_NOTPOSUPTO, /* 56 */
-
- OP_TYPESTAR, /* 57 The maximizing and minimizing versions of */
- OP_TYPEMINSTAR, /* 58 these six opcodes must come in pairs, with */
- OP_TYPEPLUS, /* 59 the minimizing one second. These codes must */
- OP_TYPEMINPLUS, /* 60 be in exactly the same order as those above. */
- OP_TYPEQUERY, /* 61 This set applies to character types such as \d */
- OP_TYPEMINQUERY, /* 62 */
-
- OP_TYPEUPTO, /* 63 From 0 to n matches */
- OP_TYPEMINUPTO, /* 64 */
- OP_TYPEEXACT, /* 65 Exactly n matches */
-
- OP_TYPEPOSSTAR, /* 66 Possessified versions */
- OP_TYPEPOSPLUS, /* 67 */
- OP_TYPEPOSQUERY, /* 68 */
- OP_TYPEPOSUPTO, /* 69 */
-
- OP_CRSTAR, /* 70 The maximizing and minimizing versions of */
- OP_CRMINSTAR, /* 71 all these opcodes must come in pairs, with */
- OP_CRPLUS, /* 72 the minimizing one second. These codes must */
- OP_CRMINPLUS, /* 73 be in exactly the same order as those above. */
- OP_CRQUERY, /* 74 These are for character classes and back refs */
- OP_CRMINQUERY, /* 75 */
- OP_CRRANGE, /* 76 These are different to the three sets above. */
- OP_CRMINRANGE, /* 77 */
-
- OP_CLASS, /* 78 Match a character class, chars < 256 only */
- OP_NCLASS, /* 79 Same, but the bitmap was created from a negative
- class - the difference is relevant only when a UTF-8
- character > 255 is encountered. */
-
- OP_XCLASS, /* 80 Extended class for handling UTF-8 chars within the
- class. This does both positive and negative. */
-
- OP_REF, /* 81 Match a back reference */
- OP_RECURSE, /* 82 Match a numbered subpattern (possibly recursive) */
- OP_CALLOUT, /* 83 Call out to external function if provided */
-
- OP_ALT, /* 84 Start of alternation */
- OP_KET, /* 85 End of group that doesn't have an unbounded repeat */
- OP_KETRMAX, /* 86 These two must remain together and in this */
- OP_KETRMIN, /* 87 order. They are for groups the repeat for ever. */
-
- /* The assertions must come before BRA, CBRA, ONCE, and COND.*/
-
- OP_ASSERT, /* 88 Positive lookahead */
- OP_ASSERT_NOT, /* 89 Negative lookahead */
- OP_ASSERTBACK, /* 90 Positive lookbehind */
- OP_ASSERTBACK_NOT, /* 91 Negative lookbehind */
- OP_REVERSE, /* 92 Move pointer back - used in lookbehind assertions */
-
- /* ONCE, BRA, CBRA, and COND must come after the assertions, with ONCE first,
- as there's a test for >= ONCE for a subpattern that isn't an assertion. */
-
- OP_ONCE, /* 93 Atomic group */
- OP_BRA, /* 94 Start of non-capturing bracket */
- OP_CBRA, /* 95 Start of capturing bracket */
- OP_COND, /* 96 Conditional group */
+ OP_CIRC, /* 25 Start of line - not multiline */
+ OP_CIRCM, /* 26 Start of line - multiline */
+ OP_DOLL, /* 27 End of line - not multiline */
+ OP_DOLLM, /* 28 End of line - multiline */
+ OP_CHAR, /* 29 Match one character, casefully */
+ OP_CHARI, /* 30 Match one character, caselessly */
+ OP_NOT, /* 31 Match one character, not the given one, casefully */
+ OP_NOTI, /* 32 Match one character, not the given one, caselessly */
+
+ /* The following sets of 13 opcodes must always be kept in step because
+ the offset from the first one is used to generate the others. */
+
+ /**** Single characters, caseful, must precede the caseless ones ****/
+
+ OP_STAR, /* 33 The maximizing and minimizing versions of */
+ OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */
+ OP_PLUS, /* 35 the minimizing one second. */
+ OP_MINPLUS, /* 36 */
+ OP_QUERY, /* 37 */
+ OP_MINQUERY, /* 38 */
+
+ OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/
+ OP_MINUPTO, /* 40 */
+ OP_EXACT, /* 41 Exactly n matches */
+
+ OP_POSSTAR, /* 42 Possessified star, caseful */
+ OP_POSPLUS, /* 43 Possessified plus, caseful */
+ OP_POSQUERY, /* 44 Posesssified query, caseful */
+ OP_POSUPTO, /* 45 Possessified upto, caseful */
+
+ /**** Single characters, caseless, must follow the caseful ones */
+
+ OP_STARI, /* 46 */
+ OP_MINSTARI, /* 47 */
+ OP_PLUSI, /* 48 */
+ OP_MINPLUSI, /* 49 */
+ OP_QUERYI, /* 50 */
+ OP_MINQUERYI, /* 51 */
+
+ OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */
+ OP_MINUPTOI, /* 53 */
+ OP_EXACTI, /* 54 */
+
+ OP_POSSTARI, /* 55 Possessified star, caseless */
+ OP_POSPLUSI, /* 56 Possessified plus, caseless */
+ OP_POSQUERYI, /* 57 Posesssified query, caseless */
+ OP_POSUPTOI, /* 58 Possessified upto, caseless */
+
+ /**** The negated ones must follow the non-negated ones, and match them ****/
+ /**** Negated single character, caseful; must precede the caseless ones ****/
+
+ OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */
+ OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */
+ OP_NOTPLUS, /* 61 the minimizing one second. They must be in */
+ OP_NOTMINPLUS, /* 62 exactly the same order as those above. */
+ OP_NOTQUERY, /* 63 */
+ OP_NOTMINQUERY, /* 64 */
+
+ OP_NOTUPTO, /* 65 From 0 to n matches, caseful */
+ OP_NOTMINUPTO, /* 66 */
+ OP_NOTEXACT, /* 67 Exactly n matches */
+
+ OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */
+ OP_NOTPOSPLUS, /* 69 */
+ OP_NOTPOSQUERY, /* 70 */
+ OP_NOTPOSUPTO, /* 71 */
+
+ /**** Negated single character, caseless; must follow the caseful ones ****/
+
+ OP_NOTSTARI, /* 72 */
+ OP_NOTMINSTARI, /* 73 */
+ OP_NOTPLUSI, /* 74 */
+ OP_NOTMINPLUSI, /* 75 */
+ OP_NOTQUERYI, /* 76 */
+ OP_NOTMINQUERYI, /* 77 */
+
+ OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */
+ OP_NOTMINUPTOI, /* 79 */
+ OP_NOTEXACTI, /* 80 Exactly n matches */
+
+ OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */
+ OP_NOTPOSPLUSI, /* 82 */
+ OP_NOTPOSQUERYI, /* 83 */
+ OP_NOTPOSUPTOI, /* 84 */
+
+ /**** Character types ****/
+
+ OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */
+ OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */
+ OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */
+ OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */
+ OP_TYPEQUERY, /* 89 */
+ OP_TYPEMINQUERY, /* 90 */
+
+ OP_TYPEUPTO, /* 91 From 0 to n matches */
+ OP_TYPEMINUPTO, /* 92 */
+ OP_TYPEEXACT, /* 93 Exactly n matches */
+
+ OP_TYPEPOSSTAR, /* 94 Possessified versions */
+ OP_TYPEPOSPLUS, /* 95 */
+ OP_TYPEPOSQUERY, /* 96 */
+ OP_TYPEPOSUPTO, /* 97 */
+
+ /* These are used for character classes and back references; only the
+ first six are the same as the sets above. */
+
+ OP_CRSTAR, /* 98 The maximizing and minimizing versions of */
+ OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */
+ OP_CRPLUS, /* 100 the minimizing one second. These codes must */
+ OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */
+ OP_CRQUERY, /* 102 */
+ OP_CRMINQUERY, /* 103 */
+
+ OP_CRRANGE, /* 104 These are different to the three sets above. */
+ OP_CRMINRANGE, /* 105 */
+
+ /* End of quantifier opcodes */
+
+ OP_CLASS, /* 106 Match a character class, chars < 256 only */
+ OP_NCLASS, /* 107 Same, but the bitmap was created from a negative
+ class - the difference is relevant only when a
+ character > 255 is encountered. */
+ OP_XCLASS, /* 108 Extended class for handling > 255 chars within the
+ class. This does both positive and negative. */
+ OP_REF, /* 109 Match a back reference, casefully */
+ OP_REFI, /* 110 Match a back reference, caselessly */
+ OP_RECURSE, /* 111 Match a numbered subpattern (possibly recursive) */
+ OP_CALLOUT, /* 112 Call out to external function if provided */
+
+ OP_ALT, /* 113 Start of alternation */
+ OP_KET, /* 114 End of group that doesn't have an unbounded repeat */
+ OP_KETRMAX, /* 115 These two must remain together and in this */
+ OP_KETRMIN, /* 116 order. They are for groups the repeat for ever. */
+ OP_KETRPOS, /* 117 Possessive unlimited repeat. */
+
+ /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four
+ asserts must remain in order. */
+
+ OP_REVERSE, /* 118 Move pointer back - used in lookbehind assertions */
+ OP_ASSERT, /* 119 Positive lookahead */
+ OP_ASSERT_NOT, /* 120 Negative lookahead */
+ OP_ASSERTBACK, /* 121 Positive lookbehind */
+ OP_ASSERTBACK_NOT, /* 122 Negative lookbehind */
+
+ /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately
+ after the assertions, with ONCE first, as there's a test for >= ONCE for a
+ subpattern that isn't an assertion. The POS versions must immediately follow
+ the non-POS versions in each case. */
+
+ OP_ONCE, /* 123 Atomic group, contains captures */
+ OP_ONCE_NC, /* 124 Atomic group containing no captures */
+ OP_BRA, /* 125 Start of non-capturing bracket */
+ OP_BRAPOS, /* 126 Ditto, with unlimited, possessive repeat */
+ OP_CBRA, /* 127 Start of capturing bracket */
+ OP_CBRAPOS, /* 128 Ditto, with unlimited, possessive repeat */
+ OP_COND, /* 129 Conditional group */
- /* These three must follow the previous three, in the same order. There's a
+ /* These five must follow the previous five, in the same order. There's a
check for >= SBRA to distinguish the two sets. */
- OP_SBRA, /* 97 Start of non-capturing bracket, check empty */
- OP_SCBRA, /* 98 Start of capturing bracket, check empty */
- OP_SCOND, /* 99 Conditional group, check empty */
+ OP_SBRA, /* 130 Start of non-capturing bracket, check empty */
+ OP_SBRAPOS, /* 131 Ditto, with unlimited, possessive repeat */
+ OP_SCBRA, /* 132 Start of capturing bracket, check empty */
+ OP_SCBRAPOS, /* 133 Ditto, with unlimited, possessive repeat */
+ OP_SCOND, /* 134 Conditional group, check empty */
/* The next two pairs must (respectively) be kept together. */
- OP_CREF, /* 100 Used to hold a capture number as condition */
- OP_NCREF, /* 101 Same, but generaged by a name reference*/
- OP_RREF, /* 102 Used to hold a recursion number as condition */
- OP_NRREF, /* 103 Same, but generaged by a name reference*/
- OP_DEF, /* 104 The DEFINE condition */
-
- OP_BRAZERO, /* 105 These two must remain together and in this */
- OP_BRAMINZERO, /* 106 order. */
+ OP_CREF, /* 135 Used to hold a capture number as condition */
+ OP_NCREF, /* 136 Same, but generated by a name reference*/
+ OP_RREF, /* 137 Used to hold a recursion number as condition */
+ OP_NRREF, /* 138 Same, but generated by a name reference*/
+ OP_DEF, /* 139 The DEFINE condition */
+
+ OP_BRAZERO, /* 140 These two must remain together and in this */
+ OP_BRAMINZERO, /* 141 order. */
+ OP_BRAPOSZERO, /* 142 */
/* These are backtracking control verbs */
- OP_MARK, /* 107 always has an argument */
- OP_PRUNE, /* 108 */
- OP_PRUNE_ARG, /* 109 same, but with argument */
- OP_SKIP, /* 110 */
- OP_SKIP_ARG, /* 111 same, but with argument */
- OP_THEN, /* 112 */
- OP_THEN_ARG, /* 113 same, but with argument */
- OP_COMMIT, /* 114 */
+ OP_MARK, /* 143 always has an argument */
+ OP_PRUNE, /* 144 */
+ OP_PRUNE_ARG, /* 145 same, but with argument */
+ OP_SKIP, /* 146 */
+ OP_SKIP_ARG, /* 147 same, but with argument */
+ OP_THEN, /* 148 */
+ OP_THEN_ARG, /* 149 same, but with argument */
+ OP_COMMIT, /* 150 */
/* These are forced failure and success verbs */
- OP_FAIL, /* 115 */
- OP_ACCEPT, /* 116 */
- OP_CLOSE, /* 117 Used before OP_ACCEPT to close open captures */
+ OP_FAIL, /* 151 */
+ OP_ACCEPT, /* 152 */
+ OP_ASSERT_ACCEPT, /* 153 Used inside assertions */
+ OP_CLOSE, /* 154 Used before OP_ACCEPT to close open captures */
/* This is used to skip a subpattern with a {0} quantifier */
- OP_SKIPZERO, /* 118 */
+ OP_SKIPZERO, /* 155 */
/* This is not an opcode, but is used to check that tables indexed by opcode
are the correct length, in order to catch updating errors - there have been
@@ -1462,29 +1800,45 @@
/* This macro defines textual names for all the opcodes. These are used only
-for debugging. The macro is referenced only in pcre_printint.c. */
+for debugging, and some of them are only partial names. The macro is referenced
+only in pcre_printint.c, which fills out the full names in many cases (and in
+some cases doesn't actually use these names at all). */
#define OP_NAME_LIST \
"End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \
"\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \
"notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \
"extuni", "\\Z", "\\z", \
- "Opt", "^", "$", "char", "charnc", "not", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
+ "^", "^", "$", "$", "char", "chari", "not", "noti", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
"*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
"*+","++", "?+", "{", \
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
"*+","++", "?+", "{", \
"*", "*?", "+", "+?", "?", "??", "{", "{", \
- "class", "nclass", "xclass", "Ref", "Recurse", "Callout", \
- "Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not", \
- "AssertB", "AssertB not", "Reverse", \
- "Once", "Bra", "CBra", "Cond", "SBra", "SCBra", "SCond", \
+ "class", "nclass", "xclass", "Ref", "Refi", \
+ "Recurse", "Callout", \
+ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \
+ "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \
+ "Once", "Once_NC", \
+ "Bra", "BraPos", "CBra", "CBraPos", \
+ "Cond", \
+ "SBra", "SBraPos", "SCBra", "SCBraPos", \
+ "SCond", \
"Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def", \
- "Brazero", "Braminzero", \
+ "Brazero", "Braminzero", "Braposzero", \
"*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \
- "*THEN", "*THEN", "*COMMIT", "*FAIL", "*ACCEPT", \
+ "*THEN", "*THEN", "*COMMIT", "*FAIL", \
+ "*ACCEPT", "*ASSERT_ACCEPT", \
"Close", "Skip zero"
@@ -1505,56 +1859,75 @@
3, 3, /* \P, \p */ \
1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \
1, /* \X */ \
- 1, 1, 2, 1, 1, /* \Z, \z, Opt, ^, $ */ \
+ 1, 1, 1, 1, 1, 1, /* \Z, \z, ^, ^M, $, $M */ \
2, /* Char - the minimum length */ \
- 2, /* Charnc - the minimum length */ \
+ 2, /* Chari - the minimum length */ \
2, /* not */ \
- /* Positive single-char repeats ** These are */ \
- 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \
- 4, 4, 4, /* upto, minupto, exact ** UTF-8 mode */ \
- 2, 2, 2, 4, /* *+, ++, ?+, upto+ */ \
+ 2, /* noti */ \
+ /* Positive single-char repeats ** These are */ \
+ 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \
+ 2+IMM2_SIZE, /* exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \
+ 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \
+ 2+IMM2_SIZE, /* exact I */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \
/* Negative single-char repeats - only for chars < 256 */ \
2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \
- 4, 4, 4, /* NOT upto, minupto, exact */ \
- 2, 2, 2, 4, /* Possessive *, +, ?, upto */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \
+ 2+IMM2_SIZE, /* NOT exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \
+ 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \
+ 2+IMM2_SIZE, /* NOT exact I */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \
/* Positive type repeats */ \
2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \
- 4, 4, 4, /* Type upto, minupto, exact */ \
- 2, 2, 2, 4, /* Possessive *+, ++, ?+, upto+ */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \
+ 2+IMM2_SIZE, /* Type exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \
/* Character class & ref repeats */ \
1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
- 5, 5, /* CRRANGE, CRMINRANGE */ \
- 33, /* CLASS */ \
- 33, /* NCLASS */ \
+ 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \
+ 1+(32/sizeof(pcre_uchar)), /* CLASS */ \
+ 1+(32/sizeof(pcre_uchar)), /* NCLASS */ \
0, /* XCLASS - variable length */ \
- 3, /* REF */ \
+ 1+IMM2_SIZE, /* REF */ \
+ 1+IMM2_SIZE, /* REFI */ \
1+LINK_SIZE, /* RECURSE */ \
2+2*LINK_SIZE, /* CALLOUT */ \
1+LINK_SIZE, /* Alt */ \
1+LINK_SIZE, /* Ket */ \
1+LINK_SIZE, /* KetRmax */ \
1+LINK_SIZE, /* KetRmin */ \
+ 1+LINK_SIZE, /* KetRpos */ \
+ 1+LINK_SIZE, /* Reverse */ \
1+LINK_SIZE, /* Assert */ \
1+LINK_SIZE, /* Assert not */ \
1+LINK_SIZE, /* Assert behind */ \
1+LINK_SIZE, /* Assert behind not */ \
- 1+LINK_SIZE, /* Reverse */ \
1+LINK_SIZE, /* ONCE */ \
+ 1+LINK_SIZE, /* ONCE_NC */ \
1+LINK_SIZE, /* BRA */ \
- 3+LINK_SIZE, /* CBRA */ \
+ 1+LINK_SIZE, /* BRAPOS */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \
1+LINK_SIZE, /* COND */ \
1+LINK_SIZE, /* SBRA */ \
- 3+LINK_SIZE, /* SCBRA */ \
+ 1+LINK_SIZE, /* SBRAPOS */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \
1+LINK_SIZE, /* SCOND */ \
- 3, 3, /* CREF, NCREF */ \
- 3, 3, /* RREF, NRREF */ \
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* CREF, NCREF */ \
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* RREF, NRREF */ \
1, /* DEF */ \
- 1, 1, /* BRAZERO, BRAMINZERO */ \
+ 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \
3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \
1, 3, /* SKIP, SKIP_ARG */ \
- 1+LINK_SIZE, 3+LINK_SIZE, /* THEN, THEN_ARG */ \
- 1, 1, 1, 3, 1 /* COMMIT, FAIL, ACCEPT, CLOSE, SKIPZERO */
-
+ 1, 3, /* THEN, THEN_ARG */ \
+ 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \
+ 1+IMM2_SIZE, 1 /* CLOSE, SKIPZERO */
/* A magic value for OP_RREF and OP_NRREF to indicate the "any recursion"
condition. */
@@ -1571,8 +1944,12 @@
ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39,
ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49,
ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
- ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68,
- ERRCOUNT };
+ ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69,
+ ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERRCOUNT };
+
+/* JIT compiling modes. The function list is indexed by them. */
+enum { JIT_COMPILE, JIT_PARTIAL_SOFT_COMPILE, JIT_PARTIAL_HARD_COMPILE,
+ JIT_NUMBER_OF_COMPILE_MODES };
/* The real format of the start of the pcre block; the index of names and the
code vector run on as long as necessary after the end. We store an explicit
@@ -1591,24 +1968,29 @@
NOTE NOTE NOTE
*/
-typedef struct real_pcre {
+#ifdef COMPILE_PCRE8
+#define REAL_PCRE real_pcre
+#else
+#define REAL_PCRE real_pcre16
+#endif
+
+typedef struct REAL_PCRE {
pcre_uint32 magic_number;
pcre_uint32 size; /* Total that was malloced */
pcre_uint32 options; /* Public options */
pcre_uint16 flags; /* Private flags */
- pcre_uint16 dummy1; /* For future use */
- pcre_uint16 top_bracket;
- pcre_uint16 top_backref;
- pcre_uint16 first_byte;
- pcre_uint16 req_byte;
+ pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */
+ pcre_uint16 top_bracket; /* Highest numbered group */
+ pcre_uint16 top_backref; /* Highest numbered back reference */
+ pcre_uint16 first_char; /* Starting character */
+ pcre_uint16 req_char; /* This character must be seen */
pcre_uint16 name_table_offset; /* Offset to name table that follows */
pcre_uint16 name_entry_size; /* Size of any name items */
pcre_uint16 name_count; /* Number of name items */
pcre_uint16 ref_count; /* Reference count */
-
- const unsigned char *tables; /* Pointer to tables or NULL for std */
- const unsigned char *nullpad; /* NULL padding */
-} real_pcre;
+ const pcre_uint8 *tables; /* Pointer to tables or NULL for std */
+ const pcre_uint8 *nullpad; /* NULL padding */
+} REAL_PCRE;
/* The format of the block used to store data from pcre_study(). The same
remark (see NOTE above) about extending this structure applies. */
@@ -1616,7 +1998,7 @@
typedef struct pcre_study_data {
pcre_uint32 size; /* Total that was malloced */
pcre_uint32 flags; /* Private flags */
- uschar start_bits[32]; /* Starting char bits */
+ pcre_uint8 start_bits[32]; /* Starting char bits */
pcre_uint32 minlength; /* Minimum subject length */
} pcre_study_data;
@@ -1635,60 +2017,71 @@
doing the compiling, so that they are thread-safe. */
typedef struct compile_data {
- const uschar *lcc; /* Points to lower casing table */
- const uschar *fcc; /* Points to case-flipping table */
- const uschar *cbits; /* Points to character type table */
- const uschar *ctypes; /* Points to table of type maps */
- const uschar *start_workspace;/* The start of working space */
- const uschar *start_code; /* The start of the compiled code */
- const uschar *start_pattern; /* The start of the pattern */
- const uschar *end_pattern; /* The end of the pattern */
- open_capitem *open_caps; /* Chain of open capture items */
- uschar *hwm; /* High watermark of workspace */
- uschar *name_table; /* The name/number table */
- int names_found; /* Number of entries so far */
- int name_entry_size; /* Size of each entry */
- int bracount; /* Count of capturing parens as we compile */
- int final_bracount; /* Saved value after first pass */
- int top_backref; /* Maximum back reference */
- unsigned int backref_map; /* Bitmap of low back refs */
- int external_options; /* External (initial) options */
- int external_flags; /* External flag bits to be set */
- int req_varyopt; /* "After variable item" flag for reqbyte */
- BOOL had_accept; /* (*ACCEPT) encountered */
- BOOL check_lookbehind; /* Lookbehinds need later checking */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- uschar nl[4]; /* Newline string when fixed length */
+ const pcre_uint8 *lcc; /* Points to lower casing table */
+ const pcre_uint8 *fcc; /* Points to case-flipping table */
+ const pcre_uint8 *cbits; /* Points to character type table */
+ const pcre_uint8 *ctypes; /* Points to table of type maps */
+ const pcre_uchar *start_workspace;/* The start of working space */
+ const pcre_uchar *start_code; /* The start of the compiled code */
+ const pcre_uchar *start_pattern; /* The start of the pattern */
+ const pcre_uchar *end_pattern; /* The end of the pattern */
+ open_capitem *open_caps; /* Chain of open capture items */
+ pcre_uchar *hwm; /* High watermark of workspace */
+ pcre_uchar *name_table; /* The name/number table */
+ int names_found; /* Number of entries so far */
+ int name_entry_size; /* Size of each entry */
+ int workspace_size; /* Size of workspace */
+ int bracount; /* Count of capturing parens as we compile */
+ int final_bracount; /* Saved value after first pass */
+ int max_lookbehind; /* Maximum lookbehind (characters) */
+ int top_backref; /* Maximum back reference */
+ unsigned int backref_map; /* Bitmap of low back refs */
+ int assert_depth; /* Depth of nested assertions */
+ int external_options; /* External (initial) options */
+ int external_flags; /* External flag bits to be set */
+ int req_varyopt; /* "After variable item" flag for reqbyte */
+ BOOL had_accept; /* (*ACCEPT) encountered */
+ BOOL check_lookbehind; /* Lookbehinds need later checking */
+ int nltype; /* Newline type */
+ int nllen; /* Newline string length */
+ pcre_uchar nl[4]; /* Newline string when fixed length */
} compile_data;
/* Structure for maintaining a chain of pointers to the currently incomplete
-branches, for testing for left recursion. */
+branches, for testing for left recursion while compiling. */
typedef struct branch_chain {
struct branch_chain *outer;
- uschar *current_branch;
+ pcre_uchar *current_branch;
} branch_chain;
/* Structure for items in a linked list that represents an explicit recursive
-call within the pattern. */
+call within the pattern; used by pcre_exec(). */
typedef struct recursion_info {
struct recursion_info *prevrec; /* Previous recursion record (or NULL) */
- int group_num; /* Number of group that was called */
- const uschar *after_call; /* "Return value": points after the call in the expr */
- int *offset_save; /* Pointer to start of saved offsets */
- int saved_max; /* Number of saved offsets */
- int save_offset_top; /* Current value of offset_top */
+ int group_num; /* Number of group that was called */
+ int *offset_save; /* Pointer to start of saved offsets */
+ int saved_max; /* Number of saved offsets */
+ PCRE_PUCHAR subject_position; /* Position at start of recursion */
} recursion_info;
+/* A similar structure for pcre_dfa_exec(). */
+
+typedef struct dfa_recursion_info {
+ struct dfa_recursion_info *prevrec;
+ int group_num;
+ PCRE_PUCHAR subject_position;
+} dfa_recursion_info;
+
/* Structure for building a chain of data for holding the values of the subject
pointer at the start of each subpattern, so as to detect when an empty string
-has been matched by a subpattern - to break infinite loops. */
+has been matched by a subpattern - to break infinite loops; used by
+pcre_exec(). */
typedef struct eptrblock {
struct eptrblock *epb_prev;
- USPTR epb_saved_eptr;
+ PCRE_PUCHAR epb_saved_eptr;
} eptrblock;
@@ -1699,61 +2092,71 @@
unsigned long int match_call_count; /* As it says */
unsigned long int match_limit; /* As it says */
unsigned long int match_limit_recursion; /* As it says */
- int *offset_vector; /* Offset vector */
- int offset_end; /* One past the end */
- int offset_max; /* The maximum usable for return data */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- int name_count; /* Number of names in name table */
- int name_entry_size; /* Size of entry in names table */
- uschar *name_table; /* Table of names */
- uschar nl[4]; /* Newline string when fixed */
- const uschar *lcc; /* Points to lower casing table */
- const uschar *ctypes; /* Points to table of type maps */
- BOOL offset_overflow; /* Set if too many extractions */
- BOOL notbol; /* NOTBOL flag */
- BOOL noteol; /* NOTEOL flag */
- BOOL utf8; /* UTF8 flag */
- BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */
- BOOL use_ucp; /* PCRE_UCP flag */
- BOOL endonly; /* Dollar not before final \n */
- BOOL notempty; /* Empty string match not wanted */
- BOOL notempty_atstart; /* Empty string match at start not wanted */
- BOOL hitend; /* Hit the end of the subject at some point */
- BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */
- const uschar *start_code; /* For use when recursing */
- USPTR start_subject; /* Start of the subject string */
- USPTR end_subject; /* End of the subject string */
- USPTR start_match_ptr; /* Start of matched string */
- USPTR end_match_ptr; /* Subject position at end match */
- USPTR start_used_ptr; /* Earliest consulted character */
- int partial; /* PARTIAL options */
- int end_offset_top; /* Highwater mark at end of match */
- int capture_last; /* Most recent capture number */
- int start_offset; /* The start offset value */
- eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */
- int eptrn; /* Next free eptrblock */
- recursion_info *recursive; /* Linked list of recursion data */
- void *callout_data; /* To pass back to callouts */
- const uschar *mark; /* Mark pointer to pass back */
+ int *offset_vector; /* Offset vector */
+ int offset_end; /* One past the end */
+ int offset_max; /* The maximum usable for return data */
+ int nltype; /* Newline type */
+ int nllen; /* Newline string length */
+ int name_count; /* Number of names in name table */
+ int name_entry_size; /* Size of entry in names table */
+ pcre_uchar *name_table; /* Table of names */
+ pcre_uchar nl[4]; /* Newline string when fixed */
+ const pcre_uint8 *lcc; /* Points to lower casing table */
+ const pcre_uint8 *fcc; /* Points to case-flipping table */
+ const pcre_uint8 *ctypes; /* Points to table of type maps */
+ BOOL offset_overflow; /* Set if too many extractions */
+ BOOL notbol; /* NOTBOL flag */
+ BOOL noteol; /* NOTEOL flag */
+ BOOL utf; /* UTF-8 / UTF-16 flag */
+ BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */
+ BOOL use_ucp; /* PCRE_UCP flag */
+ BOOL endonly; /* Dollar not before final \n */
+ BOOL notempty; /* Empty string match not wanted */
+ BOOL notempty_atstart; /* Empty string match at start not wanted */
+ BOOL hitend; /* Hit the end of the subject at some point */
+ BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */
+ BOOL hasthen; /* Pattern contains (*THEN) */
+ BOOL ignore_skip_arg; /* For re-run when SKIP name not found */
+ const pcre_uchar *start_code; /* For use when recursing */
+ PCRE_PUCHAR start_subject; /* Start of the subject string */
+ PCRE_PUCHAR end_subject; /* End of the subject string */
+ PCRE_PUCHAR start_match_ptr; /* Start of matched string */
+ PCRE_PUCHAR end_match_ptr; /* Subject position at end match */
+ PCRE_PUCHAR start_used_ptr; /* Earliest consulted character */
+ int partial; /* PARTIAL options */
+ int end_offset_top; /* Highwater mark at end of match */
+ int capture_last; /* Most recent capture number */
+ int start_offset; /* The start offset value */
+ int match_function_type; /* Set for certain special calls of MATCH() */
+ eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */
+ int eptrn; /* Next free eptrblock */
+ recursion_info *recursive; /* Linked list of recursion data */
+ void *callout_data; /* To pass back to callouts */
+ const pcre_uchar *mark; /* Mark pointer to pass back on success */
+ const pcre_uchar *nomatch_mark;/* Mark pointer to pass back on failure */
+ const pcre_uchar *once_target; /* Where to back up to for atomic groups */
+#ifdef NO_RECURSE
+ void *match_frames_base; /* For remembering malloc'd frames */
+#endif
} match_data;
/* A similar structure is used for the same purpose by the DFA matching
functions. */
typedef struct dfa_match_data {
- const uschar *start_code; /* Start of the compiled pattern */
- const uschar *start_subject; /* Start of the subject string */
- const uschar *end_subject; /* End of subject string */
- const uschar *start_used_ptr; /* Earliest consulted character */
- const uschar *tables; /* Character tables */
- int start_offset; /* The start offset value */
- int moptions; /* Match options */
- int poptions; /* Pattern options */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- uschar nl[4]; /* Newline string when fixed */
- void *callout_data; /* To pass back to callouts */
+ const pcre_uchar *start_code; /* Start of the compiled pattern */
+ const pcre_uchar *start_subject ; /* Start of the subject string */
+ const pcre_uchar *end_subject; /* End of subject string */
+ const pcre_uchar *start_used_ptr; /* Earliest consulted character */
+ const pcre_uint8 *tables; /* Character tables */
+ int start_offset; /* The start offset value */
+ int moptions; /* Match options */
+ int poptions; /* Pattern options */
+ int nltype; /* Newline type */
+ int nllen; /* Newline string length */
+ pcre_uchar nl[4]; /* Newline string when fixed */
+ void *callout_data; /* To pass back to callouts */
+ dfa_recursion_info *recursive; /* Linked list of recursion data */
} dfa_match_data;
/* Bit definitions for entries in the pcre_ctypes table. */
@@ -1789,6 +2192,28 @@
#define ctypes_offset (cbits_offset + cbit_length)
#define tables_length (ctypes_offset + 256)
+/* Internal function and data prefixes. */
+
+#ifdef COMPILE_PCRE8
+#ifndef PUBL
+#define PUBL(name) pcre_##name
+#endif
+#ifndef PRIV
+#define PRIV(name) _pcre_##name
+#endif
+#else /* COMPILE_PCRE8 */
+#ifdef COMPILE_PCRE16
+#ifndef PUBL
+#define PUBL(name) pcre16_##name
+#endif
+#ifndef PRIV
+#define PRIV(name) _pcre16_##name
+#endif
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+#endif /* COMPILE_PCRE8 */
+
/* Layout of the UCP type table that translates property names into types and
codes. Each entry used to point directly to a name, but to reduce the number of
relocations in shared libraries, it now has an offset into a single string
@@ -1806,62 +2231,116 @@
but are not part of the PCRE public API. The data for these tables is in the
pcre_tables.c module. */
-extern const int _pcre_utf8_table1[];
-extern const int _pcre_utf8_table2[];
-extern const int _pcre_utf8_table3[];
-extern const uschar _pcre_utf8_table4[];
+#ifdef COMPILE_PCRE8
+
+extern const int PRIV(utf8_table1)[];
+extern const int PRIV(utf8_table1_size);
+extern const int PRIV(utf8_table2)[];
+extern const int PRIV(utf8_table3)[];
+extern const pcre_uint8 PRIV(utf8_table4)[];
-extern const int _pcre_utf8_table1_size;
+#endif /* COMPILE_PCRE8 */
-extern const char _pcre_utt_names[];
-extern const ucp_type_table _pcre_utt[];
-extern const int _pcre_utt_size;
+extern const char PRIV(utt_names)[];
+extern const ucp_type_table PRIV(utt)[];
+extern const int PRIV(utt_size);
-extern const uschar _pcre_default_tables[];
+extern const pcre_uint8 PRIV(default_tables)[];
-extern const uschar _pcre_OP_lengths[];
+extern const pcre_uint8 PRIV(OP_lengths)[];
/* Internal shared functions. These are functions that are used by more than
one of the exported public functions. They have to be "external" in the C
sense, but are not part of the PCRE public API. */
-extern const uschar *_pcre_find_bracket(const uschar *, BOOL, int);
-extern BOOL _pcre_is_newline(USPTR, int, USPTR, int *, BOOL);
-extern int _pcre_ord2utf8(int, uschar *);
-extern real_pcre *_pcre_try_flipped(const real_pcre *, real_pcre *,
- const pcre_study_data *, pcre_study_data *);
-extern int _pcre_valid_utf8(USPTR, int);
-extern BOOL _pcre_was_newline(USPTR, int, USPTR, int *, BOOL);
-extern BOOL _pcre_xclass(int, const uschar *);
+/* String comparison functions. */
+#ifdef COMPILE_PCRE8
+
+#define STRCMP_UC_UC(str1, str2) \
+ strcmp((char *)(str1), (char *)(str2))
+#define STRCMP_UC_C8(str1, str2) \
+ strcmp((char *)(str1), (str2))
+#define STRNCMP_UC_UC(str1, str2, num) \
+ strncmp((char *)(str1), (char *)(str2), (num))
+#define STRNCMP_UC_C8(str1, str2, num) \
+ strncmp((char *)(str1), (str2), (num))
+#define STRLEN_UC(str) strlen((const char *)str)
+
+#else
+extern int PRIV(strcmp_uc_uc)(const pcre_uchar *,
+ const pcre_uchar *);
+extern int PRIV(strcmp_uc_c8)(const pcre_uchar *,
+ const char *);
+extern int PRIV(strncmp_uc_uc)(const pcre_uchar *,
+ const pcre_uchar *, unsigned int num);
+extern int PRIV(strncmp_uc_c8)(const pcre_uchar *,
+ const char *, unsigned int num);
+extern unsigned int PRIV(strlen_uc)(const pcre_uchar *str);
+
+#define STRCMP_UC_UC(str1, str2) \
+ PRIV(strcmp_uc_uc)((str1), (str2))
+#define STRCMP_UC_C8(str1, str2) \
+ PRIV(strcmp_uc_c8)((str1), (str2))
+#define STRNCMP_UC_UC(str1, str2, num) \
+ PRIV(strncmp_uc_uc)((str1), (str2), (num))
+#define STRNCMP_UC_C8(str1, str2, num) \
+ PRIV(strncmp_uc_c8)((str1), (str2), (num))
+#define STRLEN_UC(str) PRIV(strlen_uc)(str)
+
+#endif /* COMPILE_PCRE8 */
+
+extern const pcre_uchar *PRIV(find_bracket)(const pcre_uchar *, BOOL, int);
+extern BOOL PRIV(is_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
+ int *, BOOL);
+extern int PRIV(ord2utf)(pcre_uint32, pcre_uchar *);
+extern int PRIV(valid_utf)(PCRE_PUCHAR, int, int *);
+extern BOOL PRIV(was_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
+ int *, BOOL);
+extern BOOL PRIV(xclass)(int, const pcre_uchar *, BOOL);
+
+#ifdef SUPPORT_JIT
+extern void PRIV(jit_compile)(const REAL_PCRE *,
+ PUBL(extra) *, int);
+extern int PRIV(jit_exec)(const REAL_PCRE *, const PUBL(extra) *,
+ const pcre_uchar *, int, int, int, int *, int);
+extern void PRIV(jit_free)(void *);
+extern int PRIV(jit_get_size)(void *);
+extern const char* PRIV(jit_get_target)(void);
+#endif
/* Unicode character database (UCD) */
typedef struct {
- uschar script;
- uschar chartype;
+ pcre_uint8 script;
+ pcre_uint8 chartype;
pcre_int32 other_case;
} ucd_record;
-extern const ucd_record _pcre_ucd_records[];
-extern const uschar _pcre_ucd_stage1[];
-extern const pcre_uint16 _pcre_ucd_stage2[];
-extern const int _pcre_ucp_gentype[];
-
+extern const ucd_record PRIV(ucd_records)[];
+extern const pcre_uint8 PRIV(ucd_stage1)[];
+extern const pcre_uint16 PRIV(ucd_stage2)[];
+extern const int PRIV(ucp_gentype)[];
+#ifdef SUPPORT_JIT
+extern const int PRIV(ucp_typerange)[];
+#endif
+#ifdef SUPPORT_UCP
/* UCD access macros */
#define UCD_BLOCK_SIZE 128
-#define GET_UCD(ch) (_pcre_ucd_records + \
- _pcre_ucd_stage2[_pcre_ucd_stage1[(ch) / UCD_BLOCK_SIZE] * \
- UCD_BLOCK_SIZE + ch % UCD_BLOCK_SIZE])
+#define GET_UCD(ch) (PRIV(ucd_records) + \
+ PRIV(ucd_stage2)[PRIV(ucd_stage1)[(ch) / UCD_BLOCK_SIZE] * \
+ UCD_BLOCK_SIZE + (ch) % UCD_BLOCK_SIZE])
#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype
#define UCD_SCRIPT(ch) GET_UCD(ch)->script
-#define UCD_CATEGORY(ch) _pcre_ucp_gentype[UCD_CHARTYPE(ch)]
+#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)]
#define UCD_OTHERCASE(ch) (ch + GET_UCD(ch)->other_case)
+#endif /* SUPPORT_UCP */
+
#endif
/* End of pcre_internal.h */
diff -Nru pcre3-8.12/pcre_jit_compile.c pcre3-8.31/pcre_jit_compile.c
--- pcre3-8.12/pcre_jit_compile.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre_jit_compile.c 2012-06-17 16:04:44.000000000 +0000
@@ -0,0 +1,7454 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+ The machine code generator part (this module) was written by Zoltan Herczeg
+ Copyright (c) 2010-2012
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#ifdef SUPPORT_JIT
+
+/* All-in-one: Since we use the JIT compiler only from here,
+we just include it. This way we don't need to touch the build
+system files. */
+
+#define SLJIT_MALLOC(size) (PUBL(malloc))(size)
+#define SLJIT_FREE(ptr) (PUBL(free))(ptr)
+#define SLJIT_CONFIG_AUTO 1
+#define SLJIT_CONFIG_STATIC 1
+#define SLJIT_VERBOSE 0
+#define SLJIT_DEBUG 0
+
+#include "sljit/sljitLir.c"
+
+#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
+#error Unsupported architecture
+#endif
+
+/* Allocate memory on the stack. Fast, but limited size. */
+#define LOCAL_SPACE_SIZE 32768
+
+#define STACK_GROWTH_RATE 8192
+
+/* Enable to check that the allocation could destroy temporaries. */
+#if defined SLJIT_DEBUG && SLJIT_DEBUG
+#define DESTROY_REGISTERS 1
+#endif
+
+/*
+Short summary about the backtracking mechanism empolyed by the jit code generator:
+
+The code generator follows the recursive nature of the PERL compatible regular
+expressions. The basic blocks of regular expressions are condition checkers
+whose execute different commands depending on the result of the condition check.
+The relationship between the operators can be horizontal (concatenation) and
+vertical (sub-expression) (See struct backtrack_common for more details).
+
+ 'ab' - 'a' and 'b' regexps are concatenated
+ 'a+' - 'a' is the sub-expression of the '+' operator
+
+The condition checkers are boolean (true/false) checkers. Machine code is generated
+for the checker itself and for the actions depending on the result of the checker.
+The 'true' case is called as the try path (expected path), and the other is called as
+the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
+branches on the try path.
+
+ Greedy star operator (*) :
+ Try path: match happens.
+ Backtrack path: match failed.
+ Non-greedy star operator (*?) :
+ Try path: no need to perform a match.
+ Backtrack path: match is required.
+
+The following example shows how the code generated for a capturing bracket
+with two alternatives. Let A, B, C, D are arbirary regular expressions, and
+we have the following regular expression:
+
+ A(B|C)D
+
+The generated code will be the following:
+
+ A try path
+ '(' try path (pushing arguments to the stack)
+ B try path
+ ')' try path (pushing arguments to the stack)
+ D try path
+ return with successful match
+
+ D backtrack path
+ ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
+ B backtrack path
+ C expected path
+ jump to D try path
+ C backtrack path
+ A backtrack path
+
+ Notice, that the order of backtrack code paths are the opposite of the fast
+ code paths. In this way the topmost value on the stack is always belong
+ to the current backtrack code path. The backtrack path must check
+ whether there is a next alternative. If so, it needs to jump back to
+ the try path eventually. Otherwise it needs to clear out its own stack
+ frame and continue the execution on the backtrack code paths.
+*/
+
+/*
+Saved stack frames:
+
+Atomic blocks and asserts require reloading the values of local variables
+when the backtrack mechanism performed. Because of OP_RECURSE, the locals
+are not necessarly known in compile time, thus we need a dynamic restore
+mechanism.
+
+The stack frames are stored in a chain list, and have the following format:
+([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
+
+Thus we can restore the locals to a particular point in the stack.
+*/
+
+typedef struct jit_arguments {
+ /* Pointers first. */
+ struct sljit_stack *stack;
+ const pcre_uchar *str;
+ const pcre_uchar *begin;
+ const pcre_uchar *end;
+ int *offsets;
+ pcre_uchar *uchar_ptr;
+ pcre_uchar *mark_ptr;
+ /* Everything else after. */
+ int offsetcount;
+ int calllimit;
+ pcre_uint8 notbol;
+ pcre_uint8 noteol;
+ pcre_uint8 notempty;
+ pcre_uint8 notempty_atstart;
+} jit_arguments;
+
+typedef struct executable_functions {
+ void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
+ PUBL(jit_callback) callback;
+ void *userdata;
+ sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
+} executable_functions;
+
+typedef struct jump_list {
+ struct sljit_jump *jump;
+ struct jump_list *next;
+} jump_list;
+
+enum stub_types { stack_alloc };
+
+typedef struct stub_list {
+ enum stub_types type;
+ int data;
+ struct sljit_jump *start;
+ struct sljit_label *leave;
+ struct stub_list *next;
+} stub_list;
+
+typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
+
+/* The following structure is the key data type for the recursive
+code generator. It is allocated by compile_trypath, and contains
+the aguments for compile_backtrackpath. Must be the first member
+of its descendants. */
+typedef struct backtrack_common {
+ /* Concatenation stack. */
+ struct backtrack_common *prev;
+ jump_list *nextbacktracks;
+ /* Internal stack (for component operators). */
+ struct backtrack_common *top;
+ jump_list *topbacktracks;
+ /* Opcode pointer. */
+ pcre_uchar *cc;
+} backtrack_common;
+
+typedef struct assert_backtrack {
+ backtrack_common common;
+ jump_list *condfailed;
+ /* Less than 0 (-1) if a frame is not needed. */
+ int framesize;
+ /* Points to our private memory word on the stack. */
+ int localptr;
+ /* For iterators. */
+ struct sljit_label *trypath;
+} assert_backtrack;
+
+typedef struct bracket_backtrack {
+ backtrack_common common;
+ /* Where to coninue if an alternative is successfully matched. */
+ struct sljit_label *alttrypath;
+ /* For rmin and rmax iterators. */
+ struct sljit_label *recursivetrypath;
+ /* For greedy ? operator. */
+ struct sljit_label *zerotrypath;
+ /* Contains the branches of a failed condition. */
+ union {
+ /* Both for OP_COND, OP_SCOND. */
+ jump_list *condfailed;
+ assert_backtrack *assert;
+ /* For OP_ONCE. -1 if not needed. */
+ int framesize;
+ } u;
+ /* Points to our private memory word on the stack. */
+ int localptr;
+} bracket_backtrack;
+
+typedef struct bracketpos_backtrack {
+ backtrack_common common;
+ /* Points to our private memory word on the stack. */
+ int localptr;
+ /* Reverting stack is needed. */
+ int framesize;
+ /* Allocated stack size. */
+ int stacksize;
+} bracketpos_backtrack;
+
+typedef struct braminzero_backtrack {
+ backtrack_common common;
+ struct sljit_label *trypath;
+} braminzero_backtrack;
+
+typedef struct iterator_backtrack {
+ backtrack_common common;
+ /* Next iteration. */
+ struct sljit_label *trypath;
+} iterator_backtrack;
+
+typedef struct recurse_entry {
+ struct recurse_entry *next;
+ /* Contains the function entry. */
+ struct sljit_label *entry;
+ /* Collects the calls until the function is not created. */
+ jump_list *calls;
+ /* Points to the starting opcode. */
+ int start;
+} recurse_entry;
+
+typedef struct recurse_backtrack {
+ backtrack_common common;
+} recurse_backtrack;
+
+typedef struct compiler_common {
+ struct sljit_compiler *compiler;
+ pcre_uchar *start;
+
+ /* Opcode local area direct map. */
+ int *localptrs;
+ int cbraptr;
+ /* OVector starting point. Must be divisible by 2. */
+ int ovector_start;
+ /* Last known position of the requested byte. */
+ int req_char_ptr;
+ /* Head of the last recursion. */
+ int recursive_head;
+ /* First inspected character for partial matching. */
+ int start_used_ptr;
+ /* Starting pointer for partial soft matches. */
+ int hit_start;
+ /* End pointer of the first line. */
+ int first_line_end;
+ /* Points to the marked string. */
+ int mark_ptr;
+
+ /* Other */
+ const pcre_uint8 *fcc;
+ sljit_w lcc;
+ int mode;
+ int nltype;
+ int newline;
+ int bsr_nltype;
+ int endonly;
+ BOOL has_set_som;
+ sljit_w ctypes;
+ sljit_uw name_table;
+ sljit_w name_count;
+ sljit_w name_entry_size;
+
+ /* Labels and jump lists. */
+ struct sljit_label *partialmatchlabel;
+ struct sljit_label *leavelabel;
+ struct sljit_label *acceptlabel;
+ stub_list *stubs;
+ recurse_entry *entries;
+ recurse_entry *currententry;
+ jump_list *partialmatch;
+ jump_list *leave;
+ jump_list *accept;
+ jump_list *calllimit;
+ jump_list *stackalloc;
+ jump_list *revertframes;
+ jump_list *wordboundary;
+ jump_list *anynewline;
+ jump_list *hspace;
+ jump_list *vspace;
+ jump_list *casefulcmp;
+ jump_list *caselesscmp;
+ BOOL jscript_compat;
+#ifdef SUPPORT_UTF
+ BOOL utf;
+#ifdef SUPPORT_UCP
+ BOOL use_ucp;
+#endif
+ jump_list *utfreadchar;
+#ifdef COMPILE_PCRE8
+ jump_list *utfreadtype8;
+#endif
+#endif /* SUPPORT_UTF */
+#ifdef SUPPORT_UCP
+ jump_list *getucd;
+#endif
+} compiler_common;
+
+/* For byte_sequence_compare. */
+
+typedef struct compare_context {
+ int length;
+ int sourcereg;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ int ucharptr;
+ union {
+ sljit_i asint;
+ sljit_uh asushort;
+#ifdef COMPILE_PCRE8
+ sljit_ub asbyte;
+ sljit_ub asuchars[4];
+#else
+#ifdef COMPILE_PCRE16
+ sljit_uh asuchars[2];
+#endif
+#endif
+ } c;
+ union {
+ sljit_i asint;
+ sljit_uh asushort;
+#ifdef COMPILE_PCRE8
+ sljit_ub asbyte;
+ sljit_ub asuchars[4];
+#else
+#ifdef COMPILE_PCRE16
+ sljit_uh asuchars[2];
+#endif
+#endif
+ } oc;
+#endif
+} compare_context;
+
+enum {
+ frame_end = 0,
+ frame_setstrbegin = -1,
+ frame_setmark = -2
+};
+
+/* Undefine sljit macros. */
+#undef CMP
+
+/* Used for accessing the elements of the stack. */
+#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w))
+
+#define TMP1 SLJIT_TEMPORARY_REG1
+#define TMP2 SLJIT_TEMPORARY_REG3
+#define TMP3 SLJIT_TEMPORARY_EREG2
+#define STR_PTR SLJIT_SAVED_REG1
+#define STR_END SLJIT_SAVED_REG2
+#define STACK_TOP SLJIT_TEMPORARY_REG2
+#define STACK_LIMIT SLJIT_SAVED_REG3
+#define ARGUMENTS SLJIT_SAVED_EREG1
+#define CALL_COUNT SLJIT_SAVED_EREG2
+#define RETURN_ADDR SLJIT_TEMPORARY_EREG1
+
+/* Locals layout. */
+/* These two locals can be used by the current opcode. */
+#define LOCALS0 (0 * sizeof(sljit_w))
+#define LOCALS1 (1 * sizeof(sljit_w))
+/* Two local variables for possessive quantifiers (char1 cannot use them). */
+#define POSSESSIVE0 (2 * sizeof(sljit_w))
+#define POSSESSIVE1 (3 * sizeof(sljit_w))
+/* Max limit of recursions. */
+#define CALL_LIMIT (4 * sizeof(sljit_w))
+/* The output vector is stored on the stack, and contains pointers
+to characters. The vector data is divided into two groups: the first
+group contains the start / end character pointers, and the second is
+the start pointers when the end of the capturing group has not yet reached. */
+#define OVECTOR_START (common->ovector_start)
+#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w))
+#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w))
+#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start])
+
+#ifdef COMPILE_PCRE8
+#define MOV_UCHAR SLJIT_MOV_UB
+#define MOVU_UCHAR SLJIT_MOVU_UB
+#else
+#ifdef COMPILE_PCRE16
+#define MOV_UCHAR SLJIT_MOV_UH
+#define MOVU_UCHAR SLJIT_MOVU_UH
+#else
+#error Unsupported compiling mode
+#endif
+#endif
+
+/* Shortcuts. */
+#define DEFINE_COMPILER \
+ struct sljit_compiler *compiler = common->compiler
+#define OP1(op, dst, dstw, src, srcw) \
+ sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
+#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
+ sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
+#define LABEL() \
+ sljit_emit_label(compiler)
+#define JUMP(type) \
+ sljit_emit_jump(compiler, (type))
+#define JUMPTO(type, label) \
+ sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
+#define JUMPHERE(jump) \
+ sljit_set_label((jump), sljit_emit_label(compiler))
+#define CMP(type, src1, src1w, src2, src2w) \
+ sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
+#define CMPTO(type, src1, src1w, src2, src2w, label) \
+ sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
+#define COND_VALUE(op, dst, dstw, type) \
+ sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
+#define GET_LOCAL_BASE(dst, dstw, offset) \
+ sljit_get_local_base(compiler, (dst), (dstw), (offset))
+
+static pcre_uchar* bracketend(pcre_uchar* cc)
+{
+SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
+do cc += GET(cc, 1); while (*cc == OP_ALT);
+SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
+cc += 1 + LINK_SIZE;
+return cc;
+}
+
+/* Functions whose might need modification for all new supported opcodes:
+ next_opcode
+ get_localspace
+ set_localptrs
+ get_framesize
+ init_frame
+ get_localsize
+ copy_locals
+ compile_trypath
+ compile_backtrackpath
+*/
+
+static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
+{
+SLJIT_UNUSED_ARG(common);
+switch(*cc)
+ {
+ case OP_SOD:
+ case OP_SOM:
+ case OP_SET_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYNL:
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ case OP_EXTUNI:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_DEF:
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
+ case OP_COMMIT:
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ case OP_SKIPZERO:
+ return cc + 1;
+
+ case OP_ANYBYTE:
+#ifdef SUPPORT_UTF
+ if (common->utf) return NULL;
+#endif
+ return cc + 1;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ return cc;
+
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSUPTO:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSUPTOI:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSUPTO:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSUPTOI:
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ return cc;
+
+ case OP_NOTPROP:
+ case OP_PROP:
+ return cc + 1 + 2;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSUPTO:
+ case OP_REF:
+ case OP_REFI:
+ case OP_CREF:
+ case OP_NCREF:
+ case OP_RREF:
+ case OP_NRREF:
+ case OP_CLOSE:
+ cc += 1 + IMM2_SIZE;
+ return cc;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ return cc + 1 + 2 * IMM2_SIZE;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ return cc + 1 + 32 / sizeof(pcre_uchar);
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ return cc + GET(cc, 1);
+#endif
+
+ case OP_RECURSE:
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_REVERSE:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ case OP_ALT:
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ return cc + 1 + LINK_SIZE;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ return cc + 1 + LINK_SIZE + IMM2_SIZE;
+
+ case OP_MARK:
+ return cc + 1 + 2 + cc[1];
+
+ default:
+ return NULL;
+ }
+}
+
+static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
+{
+int localspace = 0;
+pcre_uchar *alternative;
+/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_SET_SOM:
+ common->has_set_som = TRUE;
+ cc += 1;
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ localspace += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ localspace += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ localspace += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_RECURSE:
+ /* Set its value only once. */
+ if (common->recursive_head == 0)
+ {
+ common->recursive_head = common->ovector_start;
+ common->ovector_start += sizeof(sljit_w);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_MARK:
+ if (common->mark_ptr == 0)
+ {
+ common->mark_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_w);
+ }
+ cc += 1 + 2 + cc[1];
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ if (cc == NULL)
+ return -1;
+ break;
+ }
+ }
+return localspace;
+}
+
+static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
+{
+pcre_uchar *cc = common->start;
+pcre_uchar *alternative;
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ common->localptrs[cc - common->start] = localptr;
+ localptr += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ common->localptrs[cc - common->start] = localptr;
+ localptr += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ {
+ common->localptrs[cc - common->start] = localptr;
+ localptr += sizeof(sljit_w);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+ }
+}
+
+/* Returns with -1 if no need for frame. */
+static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
+{
+pcre_uchar *ccend = bracketend(cc);
+int length = 0;
+BOOL possessive = FALSE;
+BOOL setsom_found = recursive;
+BOOL setmark_found = recursive;
+
+if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
+ {
+ length = 3;
+ possessive = TRUE;
+ }
+
+cc = next_opcode(common, cc);
+SLJIT_ASSERT(cc != NULL);
+while (cc < ccend)
+ switch(*cc)
+ {
+ case OP_SET_SOM:
+ SLJIT_ASSERT(common->has_set_som);
+ if (!setsom_found)
+ {
+ length += 2;
+ setsom_found = TRUE;
+ }
+ cc += 1;
+ break;
+
+ case OP_MARK:
+ SLJIT_ASSERT(common->mark_ptr != 0);
+ if (!setmark_found)
+ {
+ length += 2;
+ setmark_found = TRUE;
+ }
+ cc += 1 + 2 + cc[1];
+ break;
+
+ case OP_RECURSE:
+ if (common->has_set_som && !setsom_found)
+ {
+ length += 2;
+ setsom_found = TRUE;
+ }
+ if (common->mark_ptr != 0 && !setmark_found)
+ {
+ length += 2;
+ setmark_found = TRUE;
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ length += 3;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+
+/* Possessive quantifiers can use a special case. */
+if (SLJIT_UNLIKELY(possessive) && length == 3)
+ return -1;
+
+if (length > 0)
+ return length + 1;
+return -1;
+}
+
+static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
+{
+DEFINE_COMPILER;
+pcre_uchar *ccend = bracketend(cc);
+BOOL setsom_found = recursive;
+BOOL setmark_found = recursive;
+int offset;
+
+/* >= 1 + shortest item size (2) */
+SLJIT_UNUSED_ARG(stacktop);
+SLJIT_ASSERT(stackpos >= stacktop + 2);
+
+stackpos = STACK(stackpos);
+if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
+ cc = next_opcode(common, cc);
+SLJIT_ASSERT(cc != NULL);
+while (cc < ccend)
+ switch(*cc)
+ {
+ case OP_SET_SOM:
+ SLJIT_ASSERT(common->has_set_som);
+ if (!setsom_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_w);
+ setsom_found = TRUE;
+ }
+ cc += 1;
+ break;
+
+ case OP_MARK:
+ SLJIT_ASSERT(common->mark_ptr != 0);
+ if (!setmark_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_w);
+ setmark_found = TRUE;
+ }
+ cc += 1 + 2 + cc[1];
+ break;
+
+ case OP_RECURSE:
+ if (common->has_set_som && !setsom_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_w);
+ setsom_found = TRUE;
+ }
+ if (common->mark_ptr != 0 && !setmark_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_w);
+ setmark_found = TRUE;
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
+ stackpos += (int)sizeof(sljit_w);
+
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
+SLJIT_ASSERT(stackpos == STACK(stacktop));
+}
+
+static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
+{
+int localsize = 2;
+pcre_uchar *alternative;
+/* Calculate the sum of the local variables. */
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ localsize++;
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ localsize++;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ localsize += 2;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ localsize++;
+ cc += 1 + LINK_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+ }
+SLJIT_ASSERT(cc == ccend);
+return localsize;
+}
+
+static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
+ BOOL save, int stackptr, int stacktop)
+{
+DEFINE_COMPILER;
+int srcw[2];
+int count;
+BOOL tmp1next = TRUE;
+BOOL tmp1empty = TRUE;
+BOOL tmp2empty = TRUE;
+pcre_uchar *alternative;
+enum {
+ start,
+ loop,
+ end
+} status;
+
+status = save ? start : loop;
+stackptr = STACK(stackptr - 2);
+stacktop = STACK(stacktop - 1);
+
+if (!save)
+ {
+ stackptr += sizeof(sljit_w);
+ if (stackptr < stacktop)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ tmp1empty = FALSE;
+ }
+ if (stackptr < stacktop)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ tmp2empty = FALSE;
+ }
+ /* The tmp1next must be TRUE in either way. */
+ }
+
+while (status != end)
+ {
+ count = 0;
+ switch(status)
+ {
+ case start:
+ SLJIT_ASSERT(save && common->recursive_head != 0);
+ count = 1;
+ srcw[0] = common->recursive_head;
+ status = loop;
+ break;
+
+ case loop:
+ if (cc >= ccend)
+ {
+ status = end;
+ break;
+ }
+
+ switch(*cc)
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ count = 1;
+ srcw[0] = PRIV_DATA(cc);
+ SLJIT_ASSERT(srcw[0] != 0);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ count = 1;
+ srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ count = 2;
+ srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
+ srcw[0] = PRIV_DATA(cc);
+ SLJIT_ASSERT(srcw[0] != 0);
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ {
+ count = 1;
+ srcw[0] = PRIV_DATA(cc);
+ SLJIT_ASSERT(srcw[0] != 0);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+ break;
+
+ case end:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+ while (count > 0)
+ {
+ count--;
+ if (save)
+ {
+ if (tmp1next)
+ {
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
+ tmp1empty = FALSE;
+ tmp1next = FALSE;
+ }
+ else
+ {
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
+ tmp2empty = FALSE;
+ tmp1next = TRUE;
+ }
+ }
+ else
+ {
+ if (tmp1next)
+ {
+ SLJIT_ASSERT(!tmp1empty);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0);
+ tmp1empty = stackptr >= stacktop;
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ }
+ tmp1next = FALSE;
+ }
+ else
+ {
+ SLJIT_ASSERT(!tmp2empty);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0);
+ tmp2empty = stackptr >= stacktop;
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ }
+ tmp1next = TRUE;
+ }
+ }
+ }
+ }
+
+if (save)
+ {
+ if (tmp1next)
+ {
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ }
+ else
+ {
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ }
+ }
+SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
+}
+
+static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
+{
+return (value & (value - 1)) == 0;
+}
+
+static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
+{
+while (list)
+ {
+ /* sljit_set_label is clever enough to do nothing
+ if either the jump or the label is NULL */
+ sljit_set_label(list->jump, label);
+ list = list->next;
+ }
+}
+
+static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump)
+{
+jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
+if (list_item)
+ {
+ list_item->next = *list;
+ list_item->jump = jump;
+ *list = list_item;
+ }
+}
+
+static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start)
+{
+DEFINE_COMPILER;
+stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
+
+if (list_item)
+ {
+ list_item->type = type;
+ list_item->data = data;
+ list_item->start = start;
+ list_item->leave = LABEL();
+ list_item->next = common->stubs;
+ common->stubs = list_item;
+ }
+}
+
+static void flush_stubs(compiler_common *common)
+{
+DEFINE_COMPILER;
+stub_list* list_item = common->stubs;
+
+while (list_item)
+ {
+ JUMPHERE(list_item->start);
+ switch(list_item->type)
+ {
+ case stack_alloc:
+ add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
+ break;
+ }
+ JUMPTO(SLJIT_JUMP, list_item->leave);
+ list_item = list_item->next;
+ }
+common->stubs = NULL;
+}
+
+static SLJIT_INLINE void decrease_call_count(compiler_common *common)
+{
+DEFINE_COMPILER;
+
+OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
+add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
+}
+
+static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
+{
+/* May destroy all locals and registers except TMP2. */
+DEFINE_COMPILER;
+
+OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
+#ifdef DESTROY_REGISTERS
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
+OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
+#endif
+add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
+}
+
+static SLJIT_INLINE void free_stack(compiler_common *common, int size)
+{
+DEFINE_COMPILER;
+OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
+}
+
+static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+int i;
+/* At this point we can freely use all temporary registers. */
+/* TMP1 returns with begin - 1. */
+OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
+if (length < 8)
+ {
+ for (i = 0; i < length; i++)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);
+ }
+else
+ {
+ GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
+ loop = LABEL();
+ OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_C_NOT_ZERO, loop);
+ }
+}
+
+static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+struct sljit_jump *earlyexit;
+
+/* At this point we can freely use all registers. */
+OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
+
+OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
+if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
+OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
+if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
+OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
+OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
+GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
+/* Unlikely, but possible */
+earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
+loop = LABEL();
+OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
+OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
+/* Copy the integer value to the output buffer */
+#ifdef COMPILE_PCRE16
+OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
+#endif
+OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
+JUMPTO(SLJIT_C_NOT_ZERO, loop);
+JUMPHERE(earlyexit);
+
+/* Calculate the return value, which is the maximum ovector value. */
+if (topbracket > 1)
+ {
+ GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
+
+ /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
+ loop = LABEL();
+ OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
+ OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
+ CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
+ }
+else
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
+}
+
+static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
+{
+DEFINE_COMPILER;
+
+SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
+SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
+
+OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
+OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
+CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
+
+/* Store match begin and end. */
+OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
+OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
+OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
+OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
+#ifdef COMPILE_PCRE16
+OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
+#endif
+OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
+
+OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
+#ifdef COMPILE_PCRE16
+OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
+#endif
+OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
+
+JUMPTO(SLJIT_JUMP, leave);
+}
+
+static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
+{
+/* May destroy TMP1. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
+ {
+ /* The value of -1 must be kept for start_used_ptr! */
+ OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
+ /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
+ is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
+ jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
+ JUMPHERE(jump);
+ }
+else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
+ {
+ jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
+ JUMPHERE(jump);
+ }
+}
+
+static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
+{
+/* Detects if the character has an othercase. */
+unsigned int c;
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+ GETCHAR(c, cc);
+ if (c > 127)
+ {
+#ifdef SUPPORT_UCP
+ return c != UCD_OTHERCASE(c);
+#else
+ return FALSE;
+#endif
+ }
+#ifndef COMPILE_PCRE8
+ return common->fcc[c] != c;
+#endif
+ }
+else
+#endif
+ c = *cc;
+return MAX_255(c) ? common->fcc[c] != c : FALSE;
+}
+
+static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
+{
+/* Returns with the othercase. */
+#ifdef SUPPORT_UTF
+if (common->utf && c > 127)
+ {
+#ifdef SUPPORT_UCP
+ return UCD_OTHERCASE(c);
+#else
+ return c;
+#endif
+ }
+#endif
+return TABLE_GET(c, common->fcc, c);
+}
+
+static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc)
+{
+/* Detects if the character and its othercase has only 1 bit difference. */
+unsigned int c, oc, bit;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+int n;
+#endif
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+ GETCHAR(c, cc);
+ if (c <= 127)
+ oc = common->fcc[c];
+ else
+ {
+#ifdef SUPPORT_UCP
+ oc = UCD_OTHERCASE(c);
+#else
+ oc = c;
+#endif
+ }
+ }
+else
+ {
+ c = *cc;
+ oc = TABLE_GET(c, common->fcc, c);
+ }
+#else
+c = *cc;
+oc = TABLE_GET(c, common->fcc, c);
+#endif
+
+SLJIT_ASSERT(c != oc);
+
+bit = c ^ oc;
+/* Optimized for English alphabet. */
+if (c <= 127 && bit == 0x20)
+ return (0 << 8) | 0x20;
+
+/* Since c != oc, they must have at least 1 bit difference. */
+if (!ispowerof2(bit))
+ return 0;
+
+#ifdef COMPILE_PCRE8
+
+#ifdef SUPPORT_UTF
+if (common->utf && c > 127)
+ {
+ n = GET_EXTRALEN(*cc);
+ while ((bit & 0x3f) == 0)
+ {
+ n--;
+ bit >>= 6;
+ }
+ return (n << 8) | bit;
+ }
+#endif /* SUPPORT_UTF */
+return (0 << 8) | bit;
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+#ifdef SUPPORT_UTF
+if (common->utf && c > 65535)
+ {
+ if (bit >= (1 << 10))
+ bit >>= 10;
+ else
+ return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
+ }
+#endif /* SUPPORT_UTF */
+return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+}
+
+static void check_partial(compiler_common *common, BOOL force)
+{
+/* Checks whether a partial matching is occured. Does not modify registers. */
+DEFINE_COMPILER;
+struct sljit_jump *jump = NULL;
+
+SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
+
+if (common->mode == JIT_COMPILE)
+ return;
+
+if (!force)
+ jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
+else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
+ jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
+
+if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
+else
+ {
+ if (common->partialmatchlabel != NULL)
+ JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
+ else
+ add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
+ }
+
+if (jump != NULL)
+ JUMPHERE(jump);
+}
+
+static struct sljit_jump *check_str_end(compiler_common *common)
+{
+/* Does not affect registers. Usually used in a tight spot. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_jump *nohit;
+struct sljit_jump *return_value;
+
+if (common->mode == JIT_COMPILE)
+ return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+
+jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
+if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
+ {
+ nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
+ JUMPHERE(nohit);
+ return_value = JUMP(SLJIT_JUMP);
+ }
+else
+ {
+ return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
+ if (common->partialmatchlabel != NULL)
+ JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
+ else
+ add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
+ }
+JUMPHERE(jump);
+return return_value;
+}
+
+static void detect_partial_match(compiler_common *common, jump_list **backtracks)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+if (common->mode == JIT_COMPILE)
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+ return;
+ }
+
+/* Partial matching mode. */
+jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
+add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
+if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ }
+else
+ {
+ if (common->partialmatchlabel != NULL)
+ JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
+ else
+ add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
+ }
+JUMPHERE(jump);
+}
+
+static void read_char(compiler_common *common)
+{
+/* Reads the character into TMP1, updates STR_PTR.
+Does not check STR_END. TMP2 Destroyed. */
+DEFINE_COMPILER;
+#ifdef SUPPORT_UTF
+struct sljit_jump *jump;
+#endif
+
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+#ifdef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+#else
+#ifdef COMPILE_PCRE16
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+#endif
+#endif /* COMPILE_PCRE8 */
+ add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
+ JUMPHERE(jump);
+ }
+#endif
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+}
+
+static void peek_char(compiler_common *common)
+{
+/* Reads the character into TMP1, keeps STR_PTR.
+Does not check STR_END. TMP2 Destroyed. */
+DEFINE_COMPILER;
+#ifdef SUPPORT_UTF
+struct sljit_jump *jump;
+#endif
+
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+#ifdef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+#else
+#ifdef COMPILE_PCRE16
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+#endif
+#endif /* COMPILE_PCRE8 */
+ add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ JUMPHERE(jump);
+ }
+#endif
+}
+
+static void read_char8_type(compiler_common *common)
+{
+/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
+DEFINE_COMPILER;
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+struct sljit_jump *jump;
+#endif
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#ifdef COMPILE_PCRE8
+ /* This can be an extra read in some situations, but hopefully
+ it is needed in most cases. */
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+ jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
+ add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
+ JUMPHERE(jump);
+#else
+#ifdef COMPILE_PCRE16
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+ JUMPHERE(jump);
+ /* Skip low surrogate if necessary. */
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+#endif
+#endif /* COMPILE_PCRE8 */
+ return;
+ }
+#endif
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#ifdef COMPILE_PCRE16
+/* The ctypes array contains only 256 values. */
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+#ifdef COMPILE_PCRE16
+JUMPHERE(jump);
+#endif
+}
+
+static void skip_char_back(compiler_common *common)
+{
+/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
+DEFINE_COMPILER;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+struct sljit_label *label;
+
+if (common->utf)
+ {
+ label = LABEL();
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
+ CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
+ return;
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ /* Skip low surrogate if necessary. */
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ return;
+ }
+#endif
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+}
+
+static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue)
+{
+/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
+DEFINE_COMPILER;
+
+if (nltype == NLTYPE_ANY)
+ {
+ add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ }
+else if (nltype == NLTYPE_ANYCRLF)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ }
+else
+ {
+ SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
+ add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
+ }
+}
+
+#ifdef SUPPORT_UTF
+
+#ifdef COMPILE_PCRE8
+static void do_utfreadchar(compiler_common *common)
+{
+/* Fast decoding a UTF-8 character. TMP1 contains the first byte
+of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+/* Searching for the first zero. */
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
+jump = JUMP(SLJIT_C_NOT_ZERO);
+/* Two byte sequence. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+JUMPHERE(jump);
+
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);
+jump = JUMP(SLJIT_C_NOT_ZERO);
+/* Three byte sequence. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+JUMPHERE(jump);
+
+/* Four byte sequence. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void do_utfreadtype8(compiler_common *common)
+{
+/* Fast decoding a UTF-8 character type. TMP2 contains the first byte
+of the character (>= 0xc0). Return value in TMP1. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_jump *compare;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
+jump = JUMP(SLJIT_C_NOT_ZERO);
+/* Two byte sequence. */
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
+compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(compare);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+JUMPHERE(jump);
+
+/* We only have types for characters less than 256. */
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+static void do_utfreadchar(compiler_common *common)
+{
+/* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
+of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
+/* Do nothing, only return. */
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(jump);
+/* Combine two 16 bit characters. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+
+#endif /* SUPPORT_UTF */
+
+#ifdef SUPPORT_UCP
+
+/* UCD_BLOCK_SIZE must be 128 (see the assert below). */
+#define UCD_BLOCK_MASK 127
+#define UCD_BLOCK_SHIFT 7
+
+static void do_getucd(compiler_common *common)
+{
+/* Search the UCD record for the character comes in TMP1.
+Returns chartype in TMP1 and UCD offset in TMP2. */
+DEFINE_COMPILER;
+
+SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
+OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+#endif
+
+static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *mainloop;
+struct sljit_label *newlinelabel = NULL;
+struct sljit_jump *start;
+struct sljit_jump *end = NULL;
+struct sljit_jump *nl = NULL;
+#ifdef SUPPORT_UTF
+struct sljit_jump *singlechar;
+#endif
+jump_list *newline = NULL;
+BOOL newlinecheck = FALSE;
+BOOL readuchar = FALSE;
+
+if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
+ common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
+ newlinecheck = TRUE;
+
+if (firstline)
+ {
+ /* Search for the end of the first line. */
+ SLJIT_ASSERT(common->first_line_end != 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);
+
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ mainloop = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
+ else
+ {
+ end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ mainloop = LABEL();
+ /* Continual stores does not cause data dependency. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
+ read_char(common);
+ check_newlinechar(common, common->nltype, &newline, TRUE);
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
+ set_jumps(newline, LABEL());
+ }
+
+ JUMPHERE(end);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+ }
+
+start = JUMP(SLJIT_JUMP);
+
+if (newlinecheck)
+ {
+ newlinelabel = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+#ifdef COMPILE_PCRE16
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ nl = JUMP(SLJIT_JUMP);
+ }
+
+mainloop = LABEL();
+
+/* Increasing the STR_PTR here requires one less jump in the most common case. */
+#ifdef SUPPORT_UTF
+if (common->utf) readuchar = TRUE;
+#endif
+if (newlinecheck) readuchar = TRUE;
+
+if (readuchar)
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+
+if (newlinecheck)
+ CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (common->utf)
+ {
+ singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(singlechar);
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(singlechar);
+ }
+#endif
+JUMPHERE(start);
+
+if (newlinecheck)
+ {
+ JUMPHERE(end);
+ JUMPHERE(nl);
+ }
+
+return mainloop;
+}
+
+static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *leave;
+struct sljit_jump *found;
+pcre_uchar oc, bit;
+
+if (firstline)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
+ }
+
+start = LABEL();
+leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+
+oc = first_char;
+if (caseless)
+ {
+ oc = TABLE_GET(first_char, common->fcc, first_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (first_char > 127 && common->utf)
+ oc = UCD_OTHERCASE(first_char);
+#endif
+ }
+if (first_char == oc)
+ found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
+else
+ {
+ bit = first_char ^ oc;
+ if (ispowerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
+ }
+ else
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ found = JUMP(SLJIT_C_NOT_ZERO);
+ }
+ }
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+JUMPTO(SLJIT_JUMP, start);
+JUMPHERE(found);
+JUMPHERE(leave);
+
+if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+}
+
+static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+struct sljit_jump *lastchar;
+struct sljit_jump *firstchar;
+struct sljit_jump *leave;
+struct sljit_jump *foundcr = NULL;
+struct sljit_jump *notfoundnl;
+jump_list *newline = NULL;
+
+if (firstline)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
+ }
+
+if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
+#ifdef COMPILE_PCRE16
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+#endif
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+ loop = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
+
+ JUMPHERE(leave);
+ JUMPHERE(firstchar);
+ JUMPHERE(lastchar);
+
+ if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ return;
+ }
+
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+skip_char_back(common);
+
+loop = LABEL();
+read_char(common);
+lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
+ foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+check_newlinechar(common, common->nltype, &newline, FALSE);
+set_jumps(newline, loop);
+
+if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
+ {
+ leave = JUMP(SLJIT_JUMP);
+ JUMPHERE(foundcr);
+ notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+#ifdef COMPILE_PCRE16
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(notfoundnl);
+ JUMPHERE(leave);
+ }
+JUMPHERE(lastchar);
+JUMPHERE(firstchar);
+
+if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+}
+
+static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *leave;
+struct sljit_jump *found;
+#ifndef COMPILE_PCRE8
+struct sljit_jump *jump;
+#endif
+
+if (firstline)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
+ }
+
+start = LABEL();
+leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+#ifdef SUPPORT_UTF
+if (common->utf)
+ OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+#endif
+#ifndef COMPILE_PCRE8
+jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
+JUMPHERE(jump);
+#endif
+OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
+OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+found = JUMP(SLJIT_C_NOT_ZERO);
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+#endif
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+JUMPTO(SLJIT_JUMP, start);
+JUMPHERE(found);
+JUMPHERE(leave);
+
+if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+}
+
+static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+struct sljit_jump *toolong;
+struct sljit_jump *alreadyfound;
+struct sljit_jump *found;
+struct sljit_jump *foundoc = NULL;
+struct sljit_jump *notfound;
+pcre_uchar oc, bit;
+
+SLJIT_ASSERT(common->req_char_ptr != 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
+OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
+toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
+alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
+
+if (has_firstchar)
+ OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+else
+ OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
+
+loop = LABEL();
+notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
+
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
+oc = req_char;
+if (caseless)
+ {
+ oc = TABLE_GET(req_char, common->fcc, req_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (req_char > 127 && common->utf)
+ oc = UCD_OTHERCASE(req_char);
+#endif
+ }
+if (req_char == oc)
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
+else
+ {
+ bit = req_char ^ oc;
+ if (ispowerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
+ }
+ else
+ {
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
+ foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
+ }
+ }
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_JUMP, loop);
+
+JUMPHERE(found);
+if (foundoc)
+ JUMPHERE(foundoc);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);
+JUMPHERE(alreadyfound);
+JUMPHERE(toolong);
+return notfound;
+}
+
+static void do_revertframes(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *mainloop;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
+GET_LOCAL_BASE(TMP3, 0, 0);
+
+/* Drop frames until we reach STACK_TOP. */
+mainloop = LABEL();
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
+jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
+JUMPTO(SLJIT_JUMP, mainloop);
+
+JUMPHERE(jump);
+jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
+/* End of dropping frames. */
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(jump);
+jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
+/* Set string begin. */
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
+JUMPTO(SLJIT_JUMP, mainloop);
+
+JUMPHERE(jump);
+if (common->mark_ptr != 0)
+ {
+ jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
+ JUMPTO(SLJIT_JUMP, mainloop);
+
+ JUMPHERE(jump);
+ }
+
+/* Unknown command. */
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
+JUMPTO(SLJIT_JUMP, mainloop);
+}
+
+static void check_wordboundary(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *skipread;
+#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
+struct sljit_jump *jump;
+#endif
+
+SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
+
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+/* Get type of the previous char, and put it to LOCALS1. */
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
+skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
+skip_char_back(common);
+check_start_used_ptr(common);
+read_char(common);
+
+/* Testing char type. */
+#ifdef SUPPORT_UCP
+if (common->use_ucp)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ JUMPHERE(jump);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
+ }
+else
+#endif
+ {
+#ifndef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#elif defined SUPPORT_UTF
+ /* Here LOCALS1 has already been zeroed. */
+ jump = NULL;
+ if (common->utf)
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#endif /* COMPILE_PCRE8 */
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
+#ifndef COMPILE_PCRE8
+ JUMPHERE(jump);
+#elif defined SUPPORT_UTF
+ if (jump != NULL)
+ JUMPHERE(jump);
+#endif /* COMPILE_PCRE8 */
+ }
+JUMPHERE(skipread);
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+skipread = check_str_end(common);
+peek_char(common);
+
+/* Testing char type. This is a code duplication. */
+#ifdef SUPPORT_UCP
+if (common->use_ucp)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ JUMPHERE(jump);
+ }
+else
+#endif
+ {
+#ifndef COMPILE_PCRE8
+ /* TMP2 may be destroyed by peek_char. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#elif defined SUPPORT_UTF
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+ jump = NULL;
+ if (common->utf)
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#endif
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
+ OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+#ifndef COMPILE_PCRE8
+ JUMPHERE(jump);
+#elif defined SUPPORT_UTF
+ if (jump != NULL)
+ JUMPHERE(jump);
+#endif /* COMPILE_PCRE8 */
+ }
+JUMPHERE(skipread);
+
+OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+}
+
+static void check_anynewline(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
+OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+#ifdef COMPILE_PCRE8
+if (common->utf)
+ {
+#endif
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+#ifdef COMPILE_PCRE8
+ }
+#endif
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
+COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void check_hspace(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
+COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
+COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+#ifdef COMPILE_PCRE8
+if (common->utf)
+ {
+#endif
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
+#ifdef COMPILE_PCRE8
+ }
+#endif
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
+COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void check_vspace(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
+OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+#ifdef COMPILE_PCRE8
+if (common->utf)
+ {
+#endif
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+#ifdef COMPILE_PCRE8
+ }
+#endif
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
+COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#define CHAR1 STR_END
+#define CHAR2 STACK_TOP
+
+static void do_casefulcmp(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *label;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+label = LABEL();
+OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_C_NOT_ZERO, label);
+
+JUMPHERE(jump);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
+OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#define LCC_TABLE STACK_LIMIT
+
+static void do_caselesscmp(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *label;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
+OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+label = LABEL();
+OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+#ifndef COMPILE_PCRE8
+jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
+#ifndef COMPILE_PCRE8
+JUMPHERE(jump);
+jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
+#ifndef COMPILE_PCRE8
+JUMPHERE(jump);
+#endif
+jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_C_NOT_ZERO, label);
+
+JUMPHERE(jump);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
+OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#undef LCC_TABLE
+#undef CHAR1
+#undef CHAR2
+
+#if defined SUPPORT_UTF && defined SUPPORT_UCP
+
+static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
+{
+/* This function would be ineffective to do in JIT level. */
+int c1, c2;
+const pcre_uchar *src2 = args->uchar_ptr;
+const pcre_uchar *end2 = args->end;
+
+while (src1 < end1)
+ {
+ if (src2 >= end2)
+ return (pcre_uchar*)1;
+ GETCHARINC(c1, src1);
+ GETCHARINC(c2, src2);
+ if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
+ }
+return src2;
+}
+
+#endif /* SUPPORT_UTF && SUPPORT_UCP */
+
+static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
+ compare_context* context, jump_list **backtracks)
+{
+DEFINE_COMPILER;
+unsigned int othercasebit = 0;
+pcre_uchar *othercasechar = NULL;
+#ifdef SUPPORT_UTF
+int utflength;
+#endif
+
+if (caseless && char_has_othercase(common, cc))
+ {
+ othercasebit = char_get_othercase_bit(common, cc);
+ SLJIT_ASSERT(othercasebit);
+ /* Extracting bit difference info. */
+#ifdef COMPILE_PCRE8
+ othercasechar = cc + (othercasebit >> 8);
+ othercasebit &= 0xff;
+#else
+#ifdef COMPILE_PCRE16
+ othercasechar = cc + (othercasebit >> 9);
+ if ((othercasebit & 0x100) != 0)
+ othercasebit = (othercasebit & 0xff) << 8;
+ else
+ othercasebit &= 0xff;
+#endif
+#endif
+ }
+
+if (context->sourcereg == -1)
+ {
+#ifdef COMPILE_PCRE8
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else if (context->length >= 2)
+ OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else
+#endif
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#else
+#ifdef COMPILE_PCRE16
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else
+#endif
+ OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#endif
+#endif /* COMPILE_PCRE8 */
+ context->sourcereg = TMP2;
+ }
+
+#ifdef SUPPORT_UTF
+utflength = 1;
+if (common->utf && HAS_EXTRALEN(*cc))
+ utflength += GET_EXTRALEN(*cc);
+
+do
+ {
+#endif
+
+ context->length -= IN_UCHARS(1);
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+
+ /* Unaligned read is supported. */
+ if (othercasebit != 0 && othercasechar == cc)
+ {
+ context->c.asuchars[context->ucharptr] = *cc | othercasebit;
+ context->oc.asuchars[context->ucharptr] = othercasebit;
+ }
+ else
+ {
+ context->c.asuchars[context->ucharptr] = *cc;
+ context->oc.asuchars[context->ucharptr] = 0;
+ }
+ context->ucharptr++;
+
+#ifdef COMPILE_PCRE8
+ if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
+#else
+ if (context->ucharptr >= 2 || context->length == 0)
+#endif
+ {
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#ifdef COMPILE_PCRE8
+ else if (context->length >= 2)
+ OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else if (context->length >= 1)
+ OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#else
+ else if (context->length >= 2)
+ OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#endif
+ context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
+
+ switch(context->ucharptr)
+ {
+ case 4 / sizeof(pcre_uchar):
+ if (context->oc.asint != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
+ break;
+
+ case 2 / sizeof(pcre_uchar):
+ if (context->oc.asushort != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
+ break;
+
+#ifdef COMPILE_PCRE8
+ case 1:
+ if (context->oc.asbyte != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
+ break;
+#endif
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ context->ucharptr = 0;
+ }
+
+#else
+
+ /* Unaligned read is unsupported. */
+#ifdef COMPILE_PCRE8
+ if (context->length > 0)
+ OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#else
+ if (context->length > 0)
+ OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#endif
+ context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
+
+ if (othercasebit != 0 && othercasechar == cc)
+ {
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
+ }
+ else
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
+
+#endif
+
+ cc++;
+#ifdef SUPPORT_UTF
+ utflength--;
+ }
+while (utflength > 0);
+#endif
+
+return cc;
+}
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+
+#define SET_TYPE_OFFSET(value) \
+ if ((value) != typeoffset) \
+ { \
+ if ((value) > typeoffset) \
+ OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
+ else \
+ OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
+ } \
+ typeoffset = (value);
+
+#define SET_CHAR_OFFSET(value) \
+ if ((value) != charoffset) \
+ { \
+ if ((value) > charoffset) \
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \
+ else \
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \
+ } \
+ charoffset = (value);
+
+static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
+{
+DEFINE_COMPILER;
+jump_list *found = NULL;
+jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
+unsigned int c;
+int compares;
+struct sljit_jump *jump = NULL;
+pcre_uchar *ccbegin;
+#ifdef SUPPORT_UCP
+BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
+BOOL charsaved = FALSE;
+int typereg = TMP1, scriptreg = TMP1;
+unsigned int typeoffset;
+#endif
+int invertcmp, numberofcmps;
+unsigned int charoffset;
+
+/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */
+detect_partial_match(common, backtracks);
+read_char(common);
+
+if ((*cc++ & XCL_MAP) != 0)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+#ifndef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#elif defined SUPPORT_UTF
+ if (common->utf)
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#endif
+
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
+
+#ifndef COMPILE_PCRE8
+ JUMPHERE(jump);
+#elif defined SUPPORT_UTF
+ if (common->utf)
+ JUMPHERE(jump);
+#endif
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+#ifdef SUPPORT_UCP
+ charsaved = TRUE;
+#endif
+ cc += 32 / sizeof(pcre_uchar);
+ }
+
+/* Scanning the necessary info. */
+ccbegin = cc;
+compares = 0;
+while (*cc != XCL_END)
+ {
+ compares++;
+ if (*cc == XCL_SINGLE)
+ {
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+#ifdef SUPPORT_UCP
+ needschar = TRUE;
+#endif
+ }
+ else if (*cc == XCL_RANGE)
+ {
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ cc++;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+#ifdef SUPPORT_UCP
+ needschar = TRUE;
+#endif
+ }
+#ifdef SUPPORT_UCP
+ else
+ {
+ SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
+ cc++;
+ switch(*cc)
+ {
+ case PT_ANY:
+ break;
+
+ case PT_LAMP:
+ case PT_GC:
+ case PT_PC:
+ case PT_ALNUM:
+ needstype = TRUE;
+ break;
+
+ case PT_SC:
+ needsscript = TRUE;
+ break;
+
+ case PT_SPACE:
+ case PT_PXSPACE:
+ case PT_WORD:
+ needstype = TRUE;
+ needschar = TRUE;
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ cc += 2;
+ }
+#endif
+ }
+
+#ifdef SUPPORT_UCP
+/* Simple register allocation. TMP1 is preferred if possible. */
+if (needstype || needsscript)
+ {
+ if (needschar && !charsaved)
+ OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ if (needschar)
+ {
+ if (needstype)
+ {
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
+ typereg = RETURN_ADDR;
+ }
+
+ if (needsscript)
+ scriptreg = TMP3;
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+ }
+ else if (needstype && needsscript)
+ scriptreg = TMP3;
+ /* In all other cases only one of them was specified, and that can goes to TMP1. */
+
+ if (needsscript)
+ {
+ if (scriptreg == TMP1)
+ {
+ OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
+ OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
+ }
+ else
+ {
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
+ OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
+ }
+ }
+ }
+#endif
+
+/* Generating code. */
+cc = ccbegin;
+charoffset = 0;
+numberofcmps = 0;
+#ifdef SUPPORT_UCP
+typeoffset = 0;
+#endif
+
+while (*cc != XCL_END)
+ {
+ compares--;
+ invertcmp = (compares == 0 && list != backtracks);
+ jump = NULL;
+
+ if (*cc == XCL_SINGLE)
+ {
+ cc ++;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHARINC(c, cc);
+ }
+ else
+#endif
+ c = *cc++;
+
+ if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ numberofcmps++;
+ }
+ else if (numberofcmps > 0)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ numberofcmps = 0;
+ }
+ else
+ {
+ jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
+ numberofcmps = 0;
+ }
+ }
+ else if (*cc == XCL_RANGE)
+ {
+ cc ++;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHARINC(c, cc);
+ }
+ else
+#endif
+ c = *cc++;
+ SET_CHAR_OFFSET(c);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHARINC(c, cc);
+ }
+ else
+#endif
+ c = *cc++;
+ if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ numberofcmps++;
+ }
+ else if (numberofcmps > 0)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ numberofcmps = 0;
+ }
+ else
+ {
+ jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
+ numberofcmps = 0;
+ }
+ }
+#ifdef SUPPORT_UCP
+ else
+ {
+ if (*cc == XCL_NOTPROP)
+ invertcmp ^= 0x1;
+ cc++;
+ switch(*cc)
+ {
+ case PT_ANY:
+ if (list != backtracks)
+ {
+ if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
+ continue;
+ }
+ else if (cc[-1] == XCL_NOTPROP)
+ continue;
+ jump = JUMP(SLJIT_JUMP);
+ break;
+
+ case PT_LAMP:
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_GC:
+ c = PRIV(ucp_typerange)[(int)cc[1] * 2];
+ SET_TYPE_OFFSET(c);
+ jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
+ break;
+
+ case PT_PC:
+ jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
+ break;
+
+ case PT_SC:
+ jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]);
+ break;
+
+ case PT_SPACE:
+ case PT_PXSPACE:
+ if (*cc == PT_SPACE)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset);
+ }
+ SET_CHAR_OFFSET(9);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ if (*cc == PT_SPACE)
+ JUMPHERE(jump);
+
+ SET_TYPE_OFFSET(ucp_Zl);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_WORD:
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ /* ... fall through */
+
+ case PT_ALNUM:
+ SET_TYPE_OFFSET(ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ SET_TYPE_OFFSET(ucp_Nd);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ break;
+ }
+ cc += 2;
+ }
+#endif
+
+ if (jump != NULL)
+ add_jump(compiler, compares > 0 ? list : backtracks, jump);
+ }
+
+if (found != NULL)
+ set_jumps(found, LABEL());
+}
+
+#undef SET_TYPE_OFFSET
+#undef SET_CHAR_OFFSET
+
+#endif
+
+static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
+{
+DEFINE_COMPILER;
+int length;
+unsigned int c, oc, bit;
+compare_context context;
+struct sljit_jump *jump[4];
+#ifdef SUPPORT_UTF
+struct sljit_label *label;
+#ifdef SUPPORT_UCP
+pcre_uchar propdata[5];
+#endif
+#endif
+
+switch(type)
+ {
+ case OP_SOD:
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
+ return cc;
+
+ case OP_SOM:
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
+ return cc;
+
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ return cc;
+
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ detect_partial_match(common, backtracks);
+ read_char8_type(common);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
+ add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
+ return cc;
+
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ detect_partial_match(common, backtracks);
+ read_char8_type(common);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
+ add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
+ return cc;
+
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ detect_partial_match(common, backtracks);
+ read_char8_type(common);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
+ add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
+ return cc;
+
+ case OP_ANY:
+ detect_partial_match(common, backtracks);
+ read_char(common);
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
+ if (common->mode != JIT_PARTIAL_HARD_COMPILE)
+ jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ else
+ jump[1] = check_str_end(common);
+
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
+ if (jump[1] != NULL)
+ JUMPHERE(jump[1]);
+ JUMPHERE(jump[0]);
+ }
+ else
+ check_newlinechar(common, common->nltype, backtracks, TRUE);
+ return cc;
+
+ case OP_ALLANY:
+ detect_partial_match(common, backtracks);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#ifdef COMPILE_PCRE8
+ jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+#else /* COMPILE_PCRE8 */
+#ifdef COMPILE_PCRE16
+ jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+#endif /* COMPILE_PCRE16 */
+#endif /* COMPILE_PCRE8 */
+ JUMPHERE(jump[0]);
+ return cc;
+ }
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ return cc;
+
+ case OP_ANYBYTE:
+ detect_partial_match(common, backtracks);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ return cc;
+
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ case OP_NOTPROP:
+ case OP_PROP:
+ propdata[0] = 0;
+ propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
+ propdata[2] = cc[0];
+ propdata[3] = cc[1];
+ propdata[4] = XCL_END;
+ compile_xclass_trypath(common, propdata, backtracks);
+ return cc + 2;
+#endif
+#endif
+
+ case OP_ANYNL:
+ detect_partial_match(common, backtracks);
+ read_char(common);
+ jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ /* We don't need to handle soft partial matching case. */
+ if (common->mode != JIT_PARTIAL_HARD_COMPILE)
+ jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ else
+ jump[1] = check_str_end(common);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ jump[3] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[0]);
+ check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
+ JUMPHERE(jump[1]);
+ JUMPHERE(jump[2]);
+ JUMPHERE(jump[3]);
+ return cc;
+
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ detect_partial_match(common, backtracks);
+ read_char(common);
+ add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ return cc;
+
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ detect_partial_match(common, backtracks);
+ read_char(common);
+ add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ return cc;
+
+#ifdef SUPPORT_UCP
+ case OP_EXTUNI:
+ detect_partial_match(common, backtracks);
+ read_char(common);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));
+
+ label = LABEL();
+ jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
+ read_char(common);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
+ CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);
+
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
+ JUMPHERE(jump[0]);
+ if (common->mode == JIT_PARTIAL_HARD_COMPILE)
+ {
+ jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
+ /* Since we successfully read a char above, partial matching must occure. */
+ check_partial(common, TRUE);
+ JUMPHERE(jump[0]);
+ }
+ return cc;
+#endif
+
+ case OP_EODN:
+ /* Requires rather complex checks. */
+ jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (common->mode == JIT_COMPILE)
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
+ else
+ {
+ jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
+ add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
+ check_partial(common, TRUE);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ JUMPHERE(jump[1]);
+ }
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else if (common->nltype == NLTYPE_FIXED)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
+ }
+ else
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
+ jump[2] = JUMP(SLJIT_C_GREATER);
+ add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
+ /* Equal. */
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+
+ JUMPHERE(jump[1]);
+ if (common->nltype == NLTYPE_ANYCRLF)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
+ read_char(common);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
+ add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+ }
+ JUMPHERE(jump[2]);
+ JUMPHERE(jump[3]);
+ }
+ JUMPHERE(jump[0]);
+ check_partial(common, FALSE);
+ return cc;
+
+ case OP_EOD:
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
+ check_partial(common, FALSE);
+ return cc;
+
+ case OP_CIRC:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ return cc;
+
+ case OP_CIRCM:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+ jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ jump[0] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[1]);
+
+ add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else
+ {
+ skip_char_back(common);
+ read_char(common);
+ check_newlinechar(common, common->nltype, backtracks, FALSE);
+ }
+ JUMPHERE(jump[0]);
+ return cc;
+
+ case OP_DOLL:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+
+ if (!common->endonly)
+ compile_char1_trypath(common, OP_EODN, cc, backtracks);
+ else
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
+ check_partial(common, FALSE);
+ }
+ return cc;
+
+ case OP_DOLLM:
+ jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ check_partial(common, FALSE);
+ jump[0] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[1]);
+
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (common->mode == JIT_COMPILE)
+ add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
+ else
+ {
+ jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
+ /* STR_PTR = STR_END - IN_UCHARS(1) */
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ check_partial(common, TRUE);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ JUMPHERE(jump[1]);
+ }
+
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else
+ {
+ peek_char(common);
+ check_newlinechar(common, common->nltype, backtracks, FALSE);
+ }
+ JUMPHERE(jump[0]);
+ return cc;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ length = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
+#endif
+ if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
+ {
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
+
+ context.length = IN_UCHARS(length);
+ context.sourcereg = -1;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ context.ucharptr = 0;
+#endif
+ return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
+ }
+ detect_partial_match(common, backtracks);
+ read_char(common);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHAR(c, cc);
+ }
+ else
+#endif
+ c = *cc;
+ if (type == OP_CHAR || !char_has_othercase(common, cc))
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ return cc + length;
+ }
+ oc = char_othercase(common, c);
+ bit = c ^ oc;
+ if (ispowerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
+ return cc + length;
+ }
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
+ return cc + length;
+
+ case OP_NOT:
+ case OP_NOTI:
+ detect_partial_match(common, backtracks);
+ length = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+#ifdef COMPILE_PCRE8
+ c = *cc;
+ if (c < 128)
+ {
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ if (type == OP_NOT || !char_has_othercase(common, cc))
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ else
+ {
+ /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
+ OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
+ }
+ /* Skip the variable-length character. */
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(jump[0]);
+ return cc + 1;
+ }
+ else
+#endif /* COMPILE_PCRE8 */
+ {
+ GETCHARLEN(c, cc, length);
+ read_char(common);
+ }
+ }
+ else
+#endif /* SUPPORT_UTF */
+ {
+ read_char(common);
+ c = *cc;
+ }
+
+ if (type == OP_NOT || !char_has_othercase(common, cc))
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ else
+ {
+ oc = char_othercase(common, c);
+ bit = c ^ oc;
+ if (ispowerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
+ }
+ else
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
+ }
+ }
+ return cc + length;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ detect_partial_match(common, backtracks);
+ read_char(common);
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ jump[0] = NULL;
+#ifdef COMPILE_PCRE8
+ /* This check only affects 8 bit mode. In other modes, we
+ always need to compare the value with 255. */
+ if (common->utf)
+#endif /* COMPILE_PCRE8 */
+ {
+ jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+ if (type == OP_CLASS)
+ {
+ add_jump(compiler, backtracks, jump[0]);
+ jump[0] = NULL;
+ }
+ }
+#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ if (jump[0] != NULL)
+ JUMPHERE(jump[0]);
+#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
+ return cc + 32 / sizeof(pcre_uchar);
+
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+ case OP_XCLASS:
+ compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);
+ return cc + GET(cc, 0) - 1;
+#endif
+
+ case OP_REVERSE:
+ length = GET(cc, 0);
+ if (length == 0)
+ return cc + LINK_SIZE;
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
+ label = LABEL();
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
+ skip_char_back(common);
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_C_NOT_ZERO, label);
+ }
+ else
+#endif
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
+ }
+ check_start_used_ptr(common);
+ return cc + LINK_SIZE;
+ }
+SLJIT_ASSERT_STOP();
+return cc;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
+{
+/* This function consumes at least one input character. */
+/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
+DEFINE_COMPILER;
+pcre_uchar *ccbegin = cc;
+compare_context context;
+int size;
+
+context.length = 0;
+do
+ {
+ if (cc >= ccend)
+ break;
+
+ if (*cc == OP_CHAR)
+ {
+ size = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[1]))
+ size += GET_EXTRALEN(cc[1]);
+#endif
+ }
+ else if (*cc == OP_CHARI)
+ {
+ size = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
+ size = 0;
+ else if (HAS_EXTRALEN(cc[1]))
+ size += GET_EXTRALEN(cc[1]);
+ }
+ else
+#endif
+ if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
+ size = 0;
+ }
+ else
+ size = 0;
+
+ cc += 1 + size;
+ context.length += IN_UCHARS(size);
+ }
+while (size > 0 && context.length <= 128);
+
+cc = ccbegin;
+if (context.length > 0)
+ {
+ /* We have a fixed-length byte sequence. */
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
+ add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
+
+ context.sourcereg = -1;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ context.ucharptr = 0;
+#endif
+ do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
+ return cc;
+ }
+
+/* A non-fixed length character will be checked if length == 0. */
+return compile_char1_trypath(common, *cc, cc + 1, backtracks);
+}
+
+static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
+{
+DEFINE_COMPILER;
+int offset = GET2(cc, 1) << 1;
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+if (!common->jscript_compat)
+ {
+ if (backtracks == NULL)
+ {
+ /* OVECTOR(1) contains the "string begin - 1" constant. */
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ return JUMP(SLJIT_C_NOT_ZERO);
+ }
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+ }
+return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+}
+
+/* Forward definitions. */
+static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
+static void compile_backtrackpath(compiler_common *, struct backtrack_common *);
+
+#define PUSH_BACKTRACK(size, ccstart, error) \
+ do \
+ { \
+ backtrack = sljit_alloc_memory(compiler, (size)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return error; \
+ memset(backtrack, 0, size); \
+ backtrack->prev = parent->top; \
+ backtrack->cc = (ccstart); \
+ parent->top = backtrack; \
+ } \
+ while (0)
+
+#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
+ do \
+ { \
+ backtrack = sljit_alloc_memory(compiler, (size)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return; \
+ memset(backtrack, 0, size); \
+ backtrack->prev = parent->top; \
+ backtrack->cc = (ccstart); \
+ parent->top = backtrack; \
+ } \
+ while (0)
+
+#define BACKTRACK_AS(type) ((type *)backtrack)
+
+static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
+{
+DEFINE_COMPILER;
+int offset = GET2(cc, 1) << 1;
+struct sljit_jump *jump = NULL;
+struct sljit_jump *partial;
+struct sljit_jump *nopartial;
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+/* OVECTOR(1) contains the "string begin - 1" constant. */
+if (withchecks && !common->jscript_compat)
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+
+#if defined SUPPORT_UTF && defined SUPPORT_UCP
+if (common->utf && *cc == OP_REFI)
+ {
+ SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ if (withchecks)
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
+
+ /* Needed to save important temporary registers. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
+ sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+ if (common->mode == JIT_COMPILE)
+ add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
+ else
+ {
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
+ nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
+ check_partial(common, FALSE);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ JUMPHERE(nopartial);
+ }
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
+ }
+else
+#endif /* SUPPORT_UTF && SUPPORT_UCP */
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
+ if (withchecks)
+ jump = JUMP(SLJIT_C_ZERO);
+
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
+ if (common->mode == JIT_COMPILE)
+ add_jump(compiler, backtracks, partial);
+
+ add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+
+ if (common->mode != JIT_COMPILE)
+ {
+ nopartial = JUMP(SLJIT_JUMP);
+ JUMPHERE(partial);
+ /* TMP2 -= STR_END - STR_PTR */
+ OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
+ partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
+ add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ JUMPHERE(partial);
+ check_partial(common, FALSE);
+ add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
+ JUMPHERE(nopartial);
+ }
+ }
+
+if (jump != NULL)
+ {
+ if (emptyfail)
+ add_jump(compiler, backtracks, jump);
+ else
+ JUMPHERE(jump);
+ }
+return cc + 1 + IMM2_SIZE;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+pcre_uchar type;
+struct sljit_label *label;
+struct sljit_jump *zerolength;
+struct sljit_jump *jump = NULL;
+pcre_uchar *ccbegin = cc;
+int min = 0, max = 0;
+BOOL minimize;
+
+PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
+
+type = cc[1 + IMM2_SIZE];
+minimize = (type & 0x1) != 0;
+switch(type)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ min = 0;
+ max = 0;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ min = 1;
+ max = 0;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ min = 0;
+ max = 1;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ min = GET2(cc, 1 + IMM2_SIZE + 1);
+ max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
+ cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
+ break;
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+if (!minimize)
+ {
+ if (min == 0)
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+ /* Temporary release of STR_PTR. */
+ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ zerolength = compile_ref_checks(common, ccbegin, NULL);
+ /* Restore if not zero length. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ }
+ else
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
+ }
+
+ if (min > 1 || max > 1)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
+
+ label = LABEL();
+ compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
+
+ if (min > 1 || max > 1)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ if (min > 1)
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
+ if (max > 1)
+ {
+ jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ JUMPHERE(jump);
+ }
+ }
+
+ if (max == 0)
+ {
+ /* Includes min > 1 case as well. */
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ }
+
+ JUMPHERE(zerolength);
+ BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
+
+ decrease_call_count(common);
+ return cc;
+ }
+
+allocate_stack(common, 2);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+if (type != OP_CRMINSTAR)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+
+if (min == 0)
+ {
+ zerolength = compile_ref_checks(common, ccbegin, NULL);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ jump = JUMP(SLJIT_JUMP);
+ }
+else
+ zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
+
+BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
+if (max > 0)
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
+
+compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+if (min > 1)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);
+ }
+else if (max > 0)
+ OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+
+if (jump != NULL)
+ JUMPHERE(jump);
+JUMPHERE(zerolength);
+
+decrease_call_count(common);
+return cc;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+recurse_entry *entry = common->entries;
+recurse_entry *prev = NULL;
+int start = GET(cc, 1);
+
+PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
+while (entry != NULL)
+ {
+ if (entry->start == start)
+ break;
+ prev = entry;
+ entry = entry->next;
+ }
+
+if (entry == NULL)
+ {
+ entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ entry->next = NULL;
+ entry->entry = NULL;
+ entry->calls = NULL;
+ entry->start = start;
+
+ if (prev != NULL)
+ prev->next = entry;
+ else
+ common->entries = entry;
+ }
+
+if (common->has_set_som && common->mark_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ }
+else if (common->has_set_som || common->mark_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
+
+if (entry->entry == NULL)
+ add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
+else
+ JUMPTO(SLJIT_FAST_CALL, entry->entry);
+/* Leave if the match is failed. */
+add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
+return cc + 1 + LINK_SIZE;
+}
+
+static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
+{
+DEFINE_COMPILER;
+int framesize;
+int localptr;
+backtrack_common altbacktrack;
+pcre_uchar *ccbegin;
+pcre_uchar opcode;
+pcre_uchar bra = OP_BRA;
+jump_list *tmp = NULL;
+jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
+jump_list **found;
+/* Saving previous accept variables. */
+struct sljit_label *save_leavelabel = common->leavelabel;
+struct sljit_label *save_acceptlabel = common->acceptlabel;
+jump_list *save_leave = common->leave;
+jump_list *save_accept = common->accept;
+struct sljit_jump *jump;
+struct sljit_jump *brajump = NULL;
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ SLJIT_ASSERT(!conditional);
+ bra = *cc;
+ cc++;
+ }
+localptr = PRIV_DATA(cc);
+SLJIT_ASSERT(localptr != 0);
+framesize = get_framesize(common, cc, FALSE);
+backtrack->framesize = framesize;
+backtrack->localptr = localptr;
+opcode = *cc;
+SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
+found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
+ccbegin = cc;
+cc += GET(cc, 1);
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a braminzero backtrack path. */
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+
+if (framesize < 0)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+else
+ {
+ allocate_stack(common, framesize + 2);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ init_frame(common, ccbegin, framesize + 1, 2, FALSE);
+ }
+
+memset(&altbacktrack, 0, sizeof(backtrack_common));
+common->leavelabel = NULL;
+common->leave = NULL;
+while (1)
+ {
+ common->acceptlabel = NULL;
+ common->accept = NULL;
+ altbacktrack.top = NULL;
+ altbacktrack.topbacktracks = NULL;
+
+ if (*ccbegin == OP_ALT)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ altbacktrack.cc = ccbegin;
+ compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ common->leavelabel = save_leavelabel;
+ common->acceptlabel = save_acceptlabel;
+ common->leave = save_leave;
+ common->accept = save_accept;
+ return NULL;
+ }
+ common->acceptlabel = LABEL();
+ if (common->accept != NULL)
+ set_jumps(common->accept, common->acceptlabel);
+
+ /* Reset stack. */
+ if (framesize < 0)
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ else {
+ if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
+ {
+ /* We don't need to keep the STR_PTR, only the previous localptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ }
+
+ if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ /* We know that STR_PTR was stored on the top of the stack. */
+ if (conditional)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else if (bra == OP_BRAZERO)
+ {
+ if (framesize < 0)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else if (framesize >= 0)
+ {
+ /* For OP_BRA and OP_BRAMINZERO. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
+ }
+ }
+ add_jump(compiler, found, JUMP(SLJIT_JUMP));
+
+ compile_backtrackpath(common, altbacktrack.top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ common->leavelabel = save_leavelabel;
+ common->acceptlabel = save_acceptlabel;
+ common->leave = save_leave;
+ common->accept = save_accept;
+ return NULL;
+ }
+ set_jumps(altbacktrack.topbacktracks, LABEL());
+
+ if (*cc != OP_ALT)
+ break;
+
+ ccbegin = cc;
+ cc += GET(cc, 1);
+ }
+/* None of them matched. */
+if (common->leave != NULL)
+ set_jumps(common->leave, LABEL());
+
+if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
+ {
+ /* Assert is failed. */
+ if (conditional || bra == OP_BRAZERO)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ if (framesize < 0)
+ {
+ /* The topmost item should be 0. */
+ if (bra == OP_BRAZERO)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ else
+ free_stack(common, 1);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* The topmost item should be 0. */
+ if (bra == OP_BRAZERO)
+ {
+ free_stack(common, framesize + 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else
+ free_stack(common, framesize + 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+ jump = JUMP(SLJIT_JUMP);
+ if (bra != OP_BRAZERO)
+ add_jump(compiler, target, jump);
+
+ /* Assert is successful. */
+ set_jumps(tmp, LABEL());
+ if (framesize < 0)
+ {
+ /* We know that STR_PTR was stored on the top of the stack. */
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ /* Keep the STR_PTR on the top of the stack. */
+ if (bra == OP_BRAZERO)
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ else if (bra == OP_BRAMINZERO)
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ }
+ else
+ {
+ if (bra == OP_BRA)
+ {
+ /* We don't need to keep the STR_PTR, only the previous localptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ else
+ {
+ /* We don't need to keep the STR_PTR, only the previous localptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
+ }
+ }
+
+ if (bra == OP_BRAZERO)
+ {
+ backtrack->trypath = LABEL();
+ sljit_set_label(jump, backtrack->trypath);
+ }
+ else if (bra == OP_BRAMINZERO)
+ {
+ JUMPTO(SLJIT_JUMP, backtrack->trypath);
+ JUMPHERE(brajump);
+ if (framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
+ }
+ set_jumps(backtrack->common.topbacktracks, LABEL());
+ }
+ }
+else
+ {
+ /* AssertNot is successful. */
+ if (framesize < 0)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (bra != OP_BRA)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ else
+ free_stack(common, 1);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* The topmost item should be 0. */
+ if (bra != OP_BRA)
+ {
+ free_stack(common, framesize + 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else
+ free_stack(common, framesize + 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+
+ if (bra == OP_BRAZERO)
+ backtrack->trypath = LABEL();
+ else if (bra == OP_BRAMINZERO)
+ {
+ JUMPTO(SLJIT_JUMP, backtrack->trypath);
+ JUMPHERE(brajump);
+ }
+
+ if (bra != OP_BRA)
+ {
+ SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
+ set_jumps(backtrack->common.topbacktracks, LABEL());
+ backtrack->common.topbacktracks = NULL;
+ }
+ }
+
+common->leavelabel = save_leavelabel;
+common->acceptlabel = save_acceptlabel;
+common->leave = save_leave;
+common->accept = save_accept;
+return cc + 1 + LINK_SIZE;
+}
+
+static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
+{
+int condition = FALSE;
+pcre_uchar *slotA = name_table;
+pcre_uchar *slotB;
+sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
+sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
+sljit_w no_capture;
+int i;
+
+locals += refno & 0xff;
+refno >>= 8;
+no_capture = locals[1];
+
+for (i = 0; i < name_count; i++)
+ {
+ if (GET2(slotA, 0) == refno) break;
+ slotA += name_entry_size;
+ }
+
+if (i < name_count)
+ {
+ /* Found a name for the number - there can be only one; duplicate names
+ for different numbers are allowed, but not vice versa. First scan down
+ for duplicates. */
+
+ slotB = slotA;
+ while (slotB > name_table)
+ {
+ slotB -= name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = locals[GET2(slotB, 0) << 1] != no_capture;
+ if (condition) break;
+ }
+ else break;
+ }
+
+ /* Scan up for duplicates */
+ if (!condition)
+ {
+ slotB = slotA;
+ for (i++; i < name_count; i++)
+ {
+ slotB += name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = locals[GET2(slotB, 0) << 1] != no_capture;
+ if (condition) break;
+ }
+ else break;
+ }
+ }
+ }
+return condition;
+}
+
+static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
+{
+int condition = FALSE;
+pcre_uchar *slotA = name_table;
+pcre_uchar *slotB;
+sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
+sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
+sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
+int i;
+
+for (i = 0; i < name_count; i++)
+ {
+ if (GET2(slotA, 0) == recno) break;
+ slotA += name_entry_size;
+ }
+
+if (i < name_count)
+ {
+ /* Found a name for the number - there can be only one; duplicate
+ names for different numbers are allowed, but not vice versa. First
+ scan down for duplicates. */
+
+ slotB = slotA;
+ while (slotB > name_table)
+ {
+ slotB -= name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = GET2(slotB, 0) == group_num;
+ if (condition) break;
+ }
+ else break;
+ }
+
+ /* Scan up for duplicates */
+ if (!condition)
+ {
+ slotB = slotA;
+ for (i++; i < name_count; i++)
+ {
+ slotB += name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = GET2(slotB, 0) == group_num;
+ if (condition) break;
+ }
+ else break;
+ }
+ }
+ }
+return condition;
+}
+
+/*
+ Handling bracketed expressions is probably the most complex part.
+
+ Stack layout naming characters:
+ S - Push the current STR_PTR
+ 0 - Push a 0 (NULL)
+ A - Push the current STR_PTR. Needed for restoring the STR_PTR
+ before the next alternative. Not pushed if there are no alternatives.
+ M - Any values pushed by the current alternative. Can be empty, or anything.
+ C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
+ L - Push the previous local (pointed by localptr) to the stack
+ () - opional values stored on the stack
+ ()* - optonal, can be stored multiple times
+
+ The following list shows the regular expression templates, their PCRE byte codes
+ and stack layout supported by pcre-sljit.
+
+ (?:) OP_BRA | OP_KET A M
+ () OP_CBRA | OP_KET C M
+ (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )*
+ OP_SBRA | OP_KETRMAX 0 L M S ( L M S )*
+ (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )*
+ OP_SBRA | OP_KETRMIN 0 L M S ( L M S )*
+ ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )*
+ OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )*
+ ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )*
+ OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )*
+ (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 )
+ (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 )
+ ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 )
+ ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 )
+ (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )*
+ OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )*
+ (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )*
+ OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )*
+ ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )*
+ OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )*
+ ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )*
+ OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )*
+
+
+ Stack layout naming characters:
+ A - Push the alternative index (starting from 0) on the stack.
+ Not pushed if there is no alternatives.
+ M - Any values pushed by the current alternative. Can be empty, or anything.
+
+ The next list shows the possible content of a bracket:
+ (|) OP_*BRA | OP_ALT ... M A
+ (?()|) OP_*COND | OP_ALT M A
+ (?>|) OP_ONCE | OP_ALT ... [stack trace] M A
+ (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A
+ Or nothing, if trace is unnecessary
+*/
+
+static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+pcre_uchar opcode;
+int localptr = 0;
+int offset = 0;
+int stacksize;
+pcre_uchar *ccbegin;
+pcre_uchar *trypath;
+pcre_uchar bra = OP_BRA;
+pcre_uchar ket;
+assert_backtrack *assert;
+BOOL has_alternatives;
+struct sljit_jump *jump;
+struct sljit_jump *skip;
+struct sljit_label *rmaxlabel = NULL;
+struct sljit_jump *braminzerojump = NULL;
+
+PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ bra = *cc;
+ cc++;
+ opcode = *cc;
+ }
+
+opcode = *cc;
+ccbegin = cc;
+trypath = ccbegin + 1 + LINK_SIZE;
+
+if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
+ {
+ /* Drop this bracket_backtrack. */
+ parent->top = backtrack->prev;
+ return bracketend(cc);
+ }
+
+ket = *(bracketend(cc) - 1 - LINK_SIZE);
+SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
+SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
+cc += GET(cc, 1);
+
+has_alternatives = *cc == OP_ALT;
+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ {
+ has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;
+ if (*trypath == OP_NRREF)
+ {
+ stacksize = GET2(trypath, 1);
+ if (common->currententry == NULL || stacksize == RREF_ANY)
+ has_alternatives = FALSE;
+ else if (common->currententry->start == 0)
+ has_alternatives = stacksize != 0;
+ else
+ has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
+ }
+ }
+
+if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
+ opcode = OP_SCOND;
+if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
+ opcode = OP_ONCE;
+
+if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ {
+ /* Capturing brackets has a pre-allocated space. */
+ offset = GET2(ccbegin, 1 + LINK_SIZE);
+ localptr = OVECTOR_PRIV(offset);
+ offset <<= 1;
+ BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
+ trypath += IMM2_SIZE;
+ }
+else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ /* Other brackets simply allocate the next entry. */
+ localptr = PRIV_DATA(ccbegin);
+ SLJIT_ASSERT(localptr != 0);
+ BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
+ if (opcode == OP_ONCE)
+ BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
+ }
+
+/* Instructions before the first alternative. */
+stacksize = 0;
+if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
+ stacksize++;
+if (bra == OP_BRAZERO)
+ stacksize++;
+
+if (stacksize > 0)
+ allocate_stack(common, stacksize);
+
+stacksize = 0;
+if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+if (bra == OP_BRAZERO)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (ket != OP_KETRMIN)
+ {
+ free_stack(common, 1);
+ braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+ else
+ {
+ if (opcode == OP_ONCE || opcode >= OP_SBRA)
+ {
+ jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* Nothing stored during the first run. */
+ skip = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump);
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
+ {
+ /* When we come from outside, localptr contains the previous STR_PTR. */
+ braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ }
+ else
+ {
+ /* Except when the whole stack frame must be saved. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));
+ }
+ JUMPHERE(skip);
+ }
+ else
+ {
+ jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ JUMPHERE(jump);
+ }
+ }
+ }
+
+if (ket == OP_KETRMIN)
+ BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
+
+if (ket == OP_KETRMAX)
+ {
+ rmaxlabel = LABEL();
+ if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
+ BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;
+ }
+
+/* Handling capturing brackets and alternatives. */
+if (opcode == OP_ONCE)
+ {
+ if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
+ {
+ /* Neither capturing brackets nor recursions are not found in the block. */
+ if (ket == OP_KETRMIN)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ }
+ else if (ket == OP_KETRMAX || has_alternatives)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+ }
+ else
+ {
+ if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
+ {
+ allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
+ }
+ else
+ {
+ allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
+ }
+ }
+ }
+else if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ {
+ /* Saving the previous values. */
+ allocate_stack(common, 3);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
+ }
+else if (opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ /* Saving the previous value. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
+else if (has_alternatives)
+ {
+ /* Pushing the starting string pointer. */
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+
+/* Generating code for the first alternative. */
+if (opcode == OP_COND || opcode == OP_SCOND)
+ {
+ if (*trypath == OP_CREF)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
+ CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+ trypath += 1 + IMM2_SIZE;
+ }
+ else if (*trypath == OP_NCREF)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ stacksize = GET2(trypath, 1);
+ jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w)));
+ GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
+ sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
+
+ JUMPHERE(jump);
+ trypath += 1 + IMM2_SIZE;
+ }
+ else if (*trypath == OP_RREF || *trypath == OP_NRREF)
+ {
+ /* Never has other case. */
+ BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
+
+ stacksize = GET2(trypath, 1);
+ if (common->currententry == NULL)
+ stacksize = 0;
+ else if (stacksize == RREF_ANY)
+ stacksize = 1;
+ else if (common->currententry->start == 0)
+ stacksize = stacksize == 0;
+ else
+ stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
+
+ if (*trypath == OP_RREF || stacksize || common->currententry == NULL)
+ {
+ SLJIT_ASSERT(!has_alternatives);
+ if (stacksize != 0)
+ trypath += 1 + IMM2_SIZE;
+ else
+ {
+ if (*cc == OP_ALT)
+ {
+ trypath = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ }
+ else
+ trypath = cc;
+ }
+ }
+ else
+ {
+ SLJIT_ASSERT(has_alternatives);
+
+ stacksize = GET2(trypath, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
+ GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
+ sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
+ trypath += 1 + IMM2_SIZE;
+ }
+ }
+ else
+ {
+ SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);
+ /* Similar code as PUSH_BACKTRACK macro. */
+ assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ memset(assert, 0, sizeof(assert_backtrack));
+ assert->common.cc = trypath;
+ BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
+ trypath = compile_assert_trypath(common, trypath, assert, TRUE);
+ }
+ }
+
+compile_trypath(common, trypath, cc, backtrack);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+
+if (opcode == OP_ONCE)
+ {
+ if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ if (ket == OP_KETRMAX)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else if (ket == OP_KETRMIN)
+ {
+ /* Move the STR_PTR to the localptr. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ }
+ else
+ {
+ stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
+ if (ket == OP_KETRMAX)
+ {
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ }
+ }
+
+stacksize = 0;
+if (ket != OP_KET || bra != OP_BRA)
+ stacksize++;
+if (has_alternatives && opcode != OP_ONCE)
+ stacksize++;
+
+if (stacksize > 0)
+ allocate_stack(common, stacksize);
+
+stacksize = 0;
+if (ket != OP_KET)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ stacksize++;
+ }
+else if (bra != OP_BRA)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+if (has_alternatives)
+ {
+ if (opcode != OP_ONCE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ if (ket != OP_KETRMAX)
+ BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
+ }
+
+/* Must be after the trypath label. */
+if (offset != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
+ }
+
+if (ket == OP_KETRMAX)
+ {
+ if (opcode == OP_ONCE || opcode >= OP_SBRA)
+ {
+ if (has_alternatives)
+ BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE)
+ {
+ CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);
+ /* Drop STR_PTR for greedy plus quantifier. */
+ if (bra != OP_BRAZERO)
+ free_stack(common, 1);
+ }
+ else
+ /* TMP2 must contain the starting STR_PTR. */
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
+ }
+ else
+ JUMPTO(SLJIT_JUMP, rmaxlabel);
+ BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
+ }
+
+if (bra == OP_BRAZERO)
+ BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
+ JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);
+ if (braminzerojump != NULL)
+ {
+ JUMPHERE(braminzerojump);
+ /* We need to release the end pointer to perform the
+ backtrack for the zero-length iteration. When
+ framesize is < 0, OP_ONCE will do the release itself. */
+ if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ else if (ket == OP_KETRMIN && opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ /* Continue to the normal backtrack. */
+ }
+
+if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
+ decrease_call_count(common);
+
+/* Skip the other alternatives. */
+while (*cc == OP_ALT)
+ cc += GET(cc, 1);
+cc += 1 + LINK_SIZE;
+return cc;
+}
+
+static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+pcre_uchar opcode;
+int localptr;
+int cbraprivptr = 0;
+int framesize;
+int stacksize;
+int offset = 0;
+BOOL zero = FALSE;
+pcre_uchar *ccbegin = NULL;
+int stack;
+struct sljit_label *loop = NULL;
+struct jump_list *emptymatch = NULL;
+
+PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
+if (*cc == OP_BRAPOSZERO)
+ {
+ zero = TRUE;
+ cc++;
+ }
+
+opcode = *cc;
+localptr = PRIV_DATA(cc);
+SLJIT_ASSERT(localptr != 0);
+BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;
+switch(opcode)
+ {
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ ccbegin = cc + 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ offset = GET2(cc, 1 + LINK_SIZE);
+ cbraprivptr = OVECTOR_PRIV(offset);
+ offset <<= 1;
+ ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+framesize = get_framesize(common, cc, FALSE);
+BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
+if (framesize < 0)
+ {
+ stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
+ if (!zero)
+ stacksize++;
+ BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
+ allocate_stack(common, stacksize);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ }
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+ if (!zero)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1);
+ }
+else
+ {
+ stacksize = framesize + 1;
+ if (!zero)
+ stacksize++;
+ if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
+ stacksize++;
+ BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
+ allocate_stack(common, stacksize);
+
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ stack = 0;
+ if (!zero)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
+ stack++;
+ }
+ if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
+ stack++;
+ }
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
+ init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);
+ }
+
+if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
+
+loop = LABEL();
+while (*cc != OP_KETRPOS)
+ {
+ backtrack->top = NULL;
+ backtrack->topbacktracks = NULL;
+ cc += GET(cc, 1);
+
+ compile_trypath(common, ccbegin, cc, backtrack);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+
+ if (framesize < 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ }
+ else
+ {
+ if (opcode == OP_SBRAPOS)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+
+ if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
+ add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
+
+ if (!zero)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
+ }
+ else
+ {
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
+ if (opcode == OP_SBRAPOS)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
+ }
+
+ if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
+ add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
+
+ if (!zero)
+ {
+ if (framesize < 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ }
+ JUMPTO(SLJIT_JUMP, loop);
+ flush_stubs(common);
+
+ compile_backtrackpath(common, backtrack->top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ set_jumps(backtrack->topbacktracks, LABEL());
+
+ if (framesize < 0)
+ {
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ else
+ {
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ /* Last alternative. */
+ if (*cc == OP_KETRPOS)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
+ }
+ }
+
+ if (*cc == OP_KETRPOS)
+ break;
+ ccbegin = cc + 1 + LINK_SIZE;
+ }
+
+backtrack->topbacktracks = NULL;
+if (!zero)
+ {
+ if (framesize < 0)
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
+ else /* TMP2 is set to [localptr] above. */
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
+ }
+
+/* None of them matched. */
+set_jumps(emptymatch, LABEL());
+decrease_call_count(common);
+return cc + 1 + LINK_SIZE;
+}
+
+static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end)
+{
+int class_len;
+
+*opcode = *cc;
+if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)
+ {
+ cc++;
+ *type = OP_CHAR;
+ }
+else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)
+ {
+ cc++;
+ *type = OP_CHARI;
+ *opcode -= OP_STARI - OP_STAR;
+ }
+else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)
+ {
+ cc++;
+ *type = OP_NOT;
+ *opcode -= OP_NOTSTAR - OP_STAR;
+ }
+else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)
+ {
+ cc++;
+ *type = OP_NOTI;
+ *opcode -= OP_NOTSTARI - OP_STAR;
+ }
+else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
+ {
+ cc++;
+ *opcode -= OP_TYPESTAR - OP_STAR;
+ *type = 0;
+ }
+else
+ {
+ SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
+ *type = *opcode;
+ cc++;
+ class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
+ *opcode = cc[class_len - 1];
+ if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
+ {
+ *opcode -= OP_CRSTAR - OP_STAR;
+ if (end != NULL)
+ *end = cc + class_len;
+ }
+ else
+ {
+ SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
+ *arg1 = GET2(cc, (class_len + IMM2_SIZE));
+ *arg2 = GET2(cc, class_len);
+
+ if (*arg2 == 0)
+ {
+ SLJIT_ASSERT(*arg1 != 0);
+ *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO;
+ }
+ if (*arg1 == *arg2)
+ *opcode = OP_EXACT;
+
+ if (end != NULL)
+ *end = cc + class_len + 2 * IMM2_SIZE;
+ }
+ return cc;
+ }
+
+if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)
+ {
+ *arg1 = GET2(cc, 0);
+ cc += IMM2_SIZE;
+ }
+
+if (*type == 0)
+ {
+ *type = *cc;
+ if (end != NULL)
+ *end = next_opcode(common, cc);
+ cc++;
+ return cc;
+ }
+
+if (end != NULL)
+ {
+ *end = cc + 1;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
+#endif
+ }
+return cc;
+}
+
+static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+pcre_uchar opcode;
+pcre_uchar type;
+int arg1 = -1, arg2 = -1;
+pcre_uchar* end;
+jump_list *nomatch = NULL;
+struct sljit_jump *jump = NULL;
+struct sljit_label *label;
+
+PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
+
+cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
+
+switch(opcode)
+ {
+ case OP_STAR:
+ case OP_PLUS:
+ case OP_UPTO:
+ case OP_CRRANGE:
+ if (type == OP_ANYNL || type == OP_EXTUNI)
+ {
+ if (opcode == OP_STAR || opcode == OP_UPTO)
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+ }
+ else
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ if (opcode == OP_UPTO || opcode == OP_CRRANGE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
+
+ label = LABEL();
+ compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
+ if (opcode == OP_UPTO || opcode == OP_CRRANGE)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ if (opcode == OP_CRRANGE && arg2 > 0)
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label);
+ if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0))
+ jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ }
+
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ if (jump != NULL)
+ JUMPHERE(jump);
+ }
+ else
+ {
+ if (opcode == OP_PLUS)
+ compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+ label = LABEL();
+ compile_char1_trypath(common, type, cc, &nomatch);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))
+ {
+ OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+ JUMPTO(SLJIT_JUMP, label);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
+ }
+ set_jumps(nomatch, LABEL());
+ if (opcode == OP_CRRANGE)
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
+ break;
+
+ case OP_MINSTAR:
+ case OP_MINPLUS:
+ if (opcode == OP_MINPLUS)
+ compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
+ break;
+
+ case OP_MINUPTO:
+ case OP_CRMINRANGE:
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+ if (opcode == OP_CRMINRANGE)
+ add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
+ BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
+ break;
+
+ case OP_QUERY:
+ case OP_MINQUERY:
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ if (opcode == OP_QUERY)
+ compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
+ BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
+ break;
+
+ case OP_EXACT:
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
+ label = LABEL();
+ compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
+ break;
+
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSUPTO:
+ if (opcode != OP_POSSTAR)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ label = LABEL();
+ compile_char1_trypath(common, type, cc, &nomatch);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ if (opcode != OP_POSUPTO)
+ {
+ if (opcode == OP_POSPLUS)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);
+ JUMPTO(SLJIT_JUMP, label);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
+ }
+ set_jumps(nomatch, LABEL());
+ if (opcode == OP_POSPLUS)
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ break;
+
+ case OP_POSQUERY:
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ compile_char1_trypath(common, type, cc, &nomatch);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ set_jumps(nomatch, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+decrease_call_count(common);
+return end;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+
+PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
+
+if (*cc == OP_FAIL)
+ {
+ add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
+ return cc + 1;
+ }
+
+if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
+ {
+ /* No need to check notempty conditions. */
+ if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
+ else
+ JUMPTO(SLJIT_JUMP, common->acceptlabel);
+ return cc + 1;
+ }
+
+if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));
+else
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
+add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
+if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+else
+ CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
+else
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);
+add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
+return cc + 1;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc)
+{
+DEFINE_COMPILER;
+int offset = GET2(cc, 1);
+
+/* Data will be discarded anyway... */
+if (common->currententry != NULL)
+ return cc + 1 + IMM2_SIZE;
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
+offset <<= 1;
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+return cc + 1 + IMM2_SIZE;
+}
+
+static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_SOD:
+ case OP_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ case OP_NOTPROP:
+ case OP_PROP:
+ case OP_ANYNL:
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ case OP_EXTUNI:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_REVERSE:
+ cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
+ break;
+
+ case OP_SET_SOM:
+ PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ cc++;
+ break;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ if (common->mode == JIT_COMPILE)
+ cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
+ else
+ cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
+ break;
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+ cc = compile_iterator_trypath(common, cc, parent);
+ break;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
+ cc = compile_iterator_trypath(common, cc, parent);
+ else
+ cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
+ break;
+
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+ case OP_XCLASS:
+ if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
+ cc = compile_iterator_trypath(common, cc, parent);
+ else
+ cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
+ break;
+#endif
+
+ case OP_REF:
+ case OP_REFI:
+ if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
+ cc = compile_ref_iterator_trypath(common, cc, parent);
+ else
+ cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
+ break;
+
+ case OP_RECURSE:
+ cc = compile_recurse_trypath(common, cc, parent);
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
+ cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
+ break;
+
+ case OP_BRAMINZERO:
+ PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
+ cc = bracketend(cc + 1);
+ if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+ else
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
+ }
+ BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();
+ if (cc[1] > OP_ASSERTBACK_NOT)
+ decrease_call_count(common);
+ break;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SCBRA:
+ case OP_SCOND:
+ cc = compile_bracket_trypath(common, cc, parent);
+ break;
+
+ case OP_BRAZERO:
+ if (cc[1] > OP_ASSERTBACK_NOT)
+ cc = compile_bracket_trypath(common, cc, parent);
+ else
+ {
+ PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
+ cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
+ }
+ break;
+
+ case OP_BRAPOS:
+ case OP_CBRAPOS:
+ case OP_SBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ cc = compile_bracketpos_trypath(common, cc, parent);
+ break;
+
+ case OP_MARK:
+ PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
+ SLJIT_ASSERT(common->mark_ptr != 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
+ cc += 1 + 2 + cc[1];
+ break;
+
+ case OP_COMMIT:
+ PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
+ cc += 1;
+ break;
+
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ cc = compile_fail_accept_trypath(common, cc, parent);
+ break;
+
+ case OP_CLOSE:
+ cc = compile_close_trypath(common, cc);
+ break;
+
+ case OP_SKIPZERO:
+ cc = bracketend(cc + 1);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ return;
+ }
+ if (cc == NULL)
+ return;
+ }
+SLJIT_ASSERT(cc == ccend);
+}
+
+#undef PUSH_BACKTRACK
+#undef PUSH_BACKTRACK_NOVALUE
+#undef BACKTRACK_AS
+
+#define COMPILE_BACKTRACKPATH(current) \
+ do \
+ { \
+ compile_backtrackpath(common, (current)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return; \
+ } \
+ while (0)
+
+#define CURRENT_AS(type) ((type *)current)
+
+static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = current->cc;
+pcre_uchar opcode;
+pcre_uchar type;
+int arg1 = -1, arg2 = -1;
+struct sljit_label *label = NULL;
+struct sljit_jump *jump = NULL;
+jump_list *jumplist = NULL;
+
+cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
+
+switch(opcode)
+ {
+ case OP_STAR:
+ case OP_PLUS:
+ case OP_UPTO:
+ case OP_CRRANGE:
+ if (type == OP_ANYNL || type == OP_EXTUNI)
+ {
+ set_jumps(current->topbacktracks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
+ }
+ else
+ {
+ if (opcode <= OP_PLUS || opcode == OP_UPTO)
+ arg2 = 0;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);
+ OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ skip_char_back(common);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
+ if (opcode == OP_CRRANGE)
+ set_jumps(current->topbacktracks, LABEL());
+ JUMPHERE(jump);
+ free_stack(common, 2);
+ if (opcode == OP_PLUS)
+ set_jumps(current->topbacktracks, LABEL());
+ }
+ break;
+
+ case OP_MINSTAR:
+ case OP_MINPLUS:
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ compile_char1_trypath(common, type, cc, &jumplist);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
+ set_jumps(jumplist, LABEL());
+ free_stack(common, 1);
+ if (opcode == OP_MINPLUS)
+ set_jumps(current->topbacktracks, LABEL());
+ break;
+
+ case OP_MINUPTO:
+ case OP_CRMINRANGE:
+ if (opcode == OP_CRMINRANGE)
+ {
+ label = LABEL();
+ set_jumps(current->topbacktracks, label);
+ }
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ compile_char1_trypath(common, type, cc, &jumplist);
+
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+
+ if (opcode == OP_CRMINRANGE)
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
+
+ if (opcode == OP_CRMINRANGE && arg1 == 0)
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
+ else
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath);
+
+ set_jumps(jumplist, LABEL());
+ free_stack(common, 2);
+ break;
+
+ case OP_QUERY:
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
+ jump = JUMP(SLJIT_JUMP);
+ set_jumps(current->topbacktracks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
+ JUMPHERE(jump);
+ free_stack(common, 1);
+ break;
+
+ case OP_MINQUERY:
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ compile_char1_trypath(common, type, cc, &jumplist);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
+ set_jumps(jumplist, LABEL());
+ JUMPHERE(jump);
+ free_stack(common, 1);
+ break;
+
+ case OP_EXACT:
+ case OP_POSPLUS:
+ set_jumps(current->topbacktracks, LABEL());
+ break;
+
+ case OP_POSSTAR:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+}
+
+static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = current->cc;
+pcre_uchar type;
+
+type = cc[1 + IMM2_SIZE];
+if ((type & 0x1) == 0)
+ {
+ set_jumps(current->topbacktracks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
+ return;
+ }
+
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
+set_jumps(current->topbacktracks, LABEL());
+free_stack(common, 2);
+}
+
+static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+
+set_jumps(current->topbacktracks, LABEL());
+
+if (common->has_set_som && common->mark_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ free_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
+ }
+else if (common->has_set_som || common->mark_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
+ }
+}
+
+static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = current->cc;
+pcre_uchar bra = OP_BRA;
+struct sljit_jump *brajump = NULL;
+
+SLJIT_ASSERT(*cc != OP_BRAMINZERO);
+if (*cc == OP_BRAZERO)
+ {
+ bra = *cc;
+ cc++;
+ }
+
+if (bra == OP_BRAZERO)
+ {
+ SLJIT_ASSERT(current->topbacktracks == NULL);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+
+if (CURRENT_AS(assert_backtrack)->framesize < 0)
+ {
+ set_jumps(current->topbacktracks, LABEL());
+
+ if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);
+ free_stack(common, 1);
+ }
+ return;
+ }
+
+if (bra == OP_BRAZERO)
+ {
+ if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);
+ free_stack(common, 1);
+ return;
+ }
+ free_stack(common, 1);
+ brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+
+if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w));
+
+ set_jumps(current->topbacktracks, LABEL());
+ }
+else
+ set_jumps(current->topbacktracks, LABEL());
+
+if (bra == OP_BRAZERO)
+ {
+ /* We know there is enough place on the stack. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);
+ JUMPHERE(brajump);
+ }
+}
+
+static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+int opcode;
+int offset = 0;
+int localptr = CURRENT_AS(bracket_backtrack)->localptr;
+int stacksize;
+int count;
+pcre_uchar *cc = current->cc;
+pcre_uchar *ccbegin;
+pcre_uchar *ccprev;
+jump_list *jumplist = NULL;
+jump_list *jumplistitem = NULL;
+pcre_uchar bra = OP_BRA;
+pcre_uchar ket;
+assert_backtrack *assert;
+BOOL has_alternatives;
+struct sljit_jump *brazero = NULL;
+struct sljit_jump *once = NULL;
+struct sljit_jump *cond = NULL;
+struct sljit_label *rminlabel = NULL;
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ bra = *cc;
+ cc++;
+ }
+
+opcode = *cc;
+ccbegin = cc;
+ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
+cc += GET(cc, 1);
+has_alternatives = *cc == OP_ALT;
+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL;
+if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
+if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
+ opcode = OP_SCOND;
+if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
+ opcode = OP_ONCE;
+
+if (ket == OP_KETRMAX)
+ {
+ if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0);
+ }
+ }
+else if (ket == OP_KETRMIN)
+ {
+ if (bra != OP_BRAMINZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (opcode >= OP_SBRA || opcode == OP_ONCE)
+ {
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath);
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath);
+ }
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ else
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);
+ }
+ rminlabel = LABEL();
+ }
+else if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
+ }
+
+if (SLJIT_UNLIKELY(opcode == OP_ONCE))
+ {
+ if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ once = JUMP(SLJIT_JUMP);
+ }
+else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ {
+ if (has_alternatives)
+ {
+ /* Always exactly one alternative. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+
+ jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
+ if (SLJIT_UNLIKELY(!jumplistitem))
+ return;
+ jumplist = jumplistitem;
+ jumplistitem->next = NULL;
+ jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
+ }
+ }
+else if (*cc == OP_ALT)
+ {
+ /* Build a jump list. Get the last successfully matched branch index. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ count = 1;
+ do
+ {
+ /* Append as the last item. */
+ if (jumplist != NULL)
+ {
+ jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list));
+ jumplistitem = jumplistitem->next;
+ }
+ else
+ {
+ jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
+ jumplist = jumplistitem;
+ }
+
+ if (SLJIT_UNLIKELY(!jumplistitem))
+ return;
+
+ jumplistitem->next = NULL;
+ jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++);
+ cc += GET(cc, 1);
+ }
+ while (*cc == OP_ALT);
+
+ cc = ccbegin + GET(ccbegin, 1);
+ }
+
+COMPILE_BACKTRACKPATH(current->top);
+if (current->topbacktracks)
+ set_jumps(current->topbacktracks, LABEL());
+
+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ {
+ /* Conditional block always has at most one alternative. */
+ if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ assert = CURRENT_AS(bracket_backtrack)->u.assert;
+ if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
+ }
+ cond = JUMP(SLJIT_JUMP);
+ set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
+ }
+ else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ cond = JUMP(SLJIT_JUMP);
+ set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL());
+ }
+ else
+ SLJIT_ASSERT(!has_alternatives);
+ }
+
+if (has_alternatives)
+ {
+ count = 1;
+ do
+ {
+ current->top = NULL;
+ current->topbacktracks = NULL;
+ current->nextbacktracks = NULL;
+ if (*cc == OP_ALT)
+ {
+ ccprev = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ if (opcode != OP_COND && opcode != OP_SCOND)
+ {
+ if (localptr != 0 && opcode != OP_ONCE)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ compile_trypath(common, ccprev, cc, current);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return;
+ }
+
+ /* Instructions after the current alternative is succesfully matched. */
+ /* There is a similar code in compile_bracket_trypath. */
+ if (opcode == OP_ONCE)
+ {
+ if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ if (ket == OP_KETRMAX)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else if (ket == OP_KETRMIN)
+ {
+ /* Move the STR_PTR to the localptr. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ }
+ else
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w));
+ if (ket == OP_KETRMAX)
+ {
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ }
+ }
+
+ stacksize = 0;
+ if (opcode != OP_ONCE)
+ stacksize++;
+ if (ket != OP_KET || bra != OP_BRA)
+ stacksize++;
+
+ if (stacksize > 0) {
+ if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
+ allocate_stack(common, stacksize);
+ else
+ {
+ /* We know we have place at least for one item on the top of the stack. */
+ SLJIT_ASSERT(stacksize == 1);
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ }
+ }
+
+ stacksize = 0;
+ if (ket != OP_KET || bra != OP_BRA)
+ {
+ if (ket != OP_KET)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+ if (opcode != OP_ONCE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
+
+ if (offset != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
+ }
+
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);
+
+ if (opcode != OP_ONCE)
+ {
+ SLJIT_ASSERT(jumplist);
+ JUMPHERE(jumplist->jump);
+ jumplist = jumplist->next;
+ }
+
+ COMPILE_BACKTRACKPATH(current->top);
+ if (current->topbacktracks)
+ set_jumps(current->topbacktracks, LABEL());
+ SLJIT_ASSERT(!current->nextbacktracks);
+ }
+ while (*cc == OP_ALT);
+ SLJIT_ASSERT(!jumplist);
+
+ if (cond != NULL)
+ {
+ SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
+ assert = CURRENT_AS(bracket_backtrack)->u.assert;
+ if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
+
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
+ }
+ JUMPHERE(cond);
+ }
+
+ /* Free the STR_PTR. */
+ if (localptr == 0)
+ free_stack(common, 1);
+ }
+
+if (offset != 0)
+ {
+ /* Using both tmp register is better for instruction scheduling. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));
+ free_stack(common, 3);
+ }
+else if (opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ }
+else if (opcode == OP_ONCE)
+ {
+ cc = ccbegin + GET(ccbegin, 1);
+ if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
+ {
+ /* Reset head and drop saved frame. */
+ stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;
+ free_stack(common, CURRENT_AS(bracket_backtrack)->u.framesize + stacksize);
+ }
+ else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
+ {
+ /* The STR_PTR must be released. */
+ free_stack(common, 1);
+ }
+
+ JUMPHERE(once);
+ /* Restore previous localptr */
+ if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w));
+ else if (ket == OP_KETRMIN)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* See the comment below. */
+ free_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+ }
+
+if (ket == OP_KETRMAX)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (bra != OP_BRAZERO)
+ free_stack(common, 1);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);
+ if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);
+ JUMPHERE(brazero);
+ free_stack(common, 1);
+ }
+ }
+else if (ket == OP_KETRMIN)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ /* OP_ONCE removes everything in case of a backtrack, so we don't
+ need to explicitly release the STR_PTR. The extra release would
+ affect badly the free_stack(2) above. */
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel);
+ if (opcode == OP_ONCE)
+ free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
+ else if (bra == OP_BRAMINZERO)
+ free_stack(common, 1);
+ }
+else if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);
+ JUMPHERE(brazero);
+ }
+}
+
+static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+int offset;
+struct sljit_jump *jump;
+
+if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
+ {
+ if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
+ {
+ offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
+ }
+ set_jumps(current->topbacktracks, LABEL());
+ free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
+ return;
+ }
+
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr);
+add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+
+if (current->topbacktracks)
+ {
+ jump = JUMP(SLJIT_JUMP);
+ set_jumps(current->topbacktracks, LABEL());
+ /* Drop the stack frame. */
+ free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
+ JUMPHERE(jump);
+ }
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));
+}
+
+static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)
+{
+assert_backtrack backtrack;
+
+current->top = NULL;
+current->topbacktracks = NULL;
+current->nextbacktracks = NULL;
+if (current->cc[1] > OP_ASSERTBACK_NOT)
+ {
+ /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */
+ compile_bracket_trypath(common, current->cc, current);
+ compile_bracket_backtrackpath(common, current->top);
+ }
+else
+ {
+ memset(&backtrack, 0, sizeof(backtrack));
+ backtrack.common.cc = current->cc;
+ backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;
+ /* Manual call of compile_assert_trypath. */
+ compile_assert_trypath(common, current->cc, &backtrack, FALSE);
+ }
+SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
+}
+
+static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+
+while (current)
+ {
+ if (current->nextbacktracks != NULL)
+ set_jumps(current->nextbacktracks, LABEL());
+ switch(*current->cc)
+ {
+ case OP_SET_SOM:
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP1, 0);
+ break;
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+ case OP_CLASS:
+ case OP_NCLASS:
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+#endif
+ compile_iterator_backtrackpath(common, current);
+ break;
+
+ case OP_REF:
+ case OP_REFI:
+ compile_ref_iterator_backtrackpath(common, current);
+ break;
+
+ case OP_RECURSE:
+ compile_recurse_backtrackpath(common, current);
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ compile_assert_backtrackpath(common, current);
+ break;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SCBRA:
+ case OP_SCOND:
+ compile_bracket_backtrackpath(common, current);
+ break;
+
+ case OP_BRAZERO:
+ if (current->cc[1] > OP_ASSERTBACK_NOT)
+ compile_bracket_backtrackpath(common, current);
+ else
+ compile_assert_backtrackpath(common, current);
+ break;
+
+ case OP_BRAPOS:
+ case OP_CBRAPOS:
+ case OP_SBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ compile_bracketpos_backtrackpath(common, current);
+ break;
+
+ case OP_BRAMINZERO:
+ compile_braminzero_backtrackpath(common, current);
+ break;
+
+ case OP_MARK:
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
+ break;
+
+ case OP_COMMIT:
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
+ if (common->leavelabel == NULL)
+ add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));
+ else
+ JUMPTO(SLJIT_JUMP, common->leavelabel);
+ break;
+
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ set_jumps(current->topbacktracks, LABEL());
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ current = current->prev;
+ }
+}
+
+static SLJIT_INLINE void compile_recurse(compiler_common *common)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = common->start + common->currententry->start;
+pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
+pcre_uchar *ccend = bracketend(cc);
+int localsize = get_localsize(common, ccbegin, ccend);
+int framesize = get_framesize(common, cc, TRUE);
+int alternativesize;
+BOOL needsframe;
+backtrack_common altbacktrack;
+struct sljit_label *save_leavelabel = common->leavelabel;
+jump_list *save_leave = common->leave;
+struct sljit_jump *jump;
+
+SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
+needsframe = framesize >= 0;
+if (!needsframe)
+ framesize = 0;
+alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
+
+SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);
+common->currententry->entry = LABEL();
+set_jumps(common->currententry->calls, common->currententry->entry);
+
+sljit_emit_fast_enter(compiler, TMP2, 0);
+allocate_stack(common, localsize + framesize + alternativesize);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);
+copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);
+if (needsframe)
+ init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
+
+if (alternativesize > 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+memset(&altbacktrack, 0, sizeof(backtrack_common));
+common->leavelabel = NULL;
+common->acceptlabel = NULL;
+common->leave = NULL;
+common->accept = NULL;
+altbacktrack.cc = ccbegin;
+cc += GET(cc, 1);
+while (1)
+ {
+ altbacktrack.top = NULL;
+ altbacktrack.topbacktracks = NULL;
+
+ if (altbacktrack.cc != ccbegin)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ common->leavelabel = save_leavelabel;
+ common->leave = save_leave;
+ return;
+ }
+
+ add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
+
+ compile_backtrackpath(common, altbacktrack.top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ common->leavelabel = save_leavelabel;
+ common->leave = save_leave;
+ return;
+ }
+ set_jumps(altbacktrack.topbacktracks, LABEL());
+
+ if (*cc != OP_ALT)
+ break;
+
+ altbacktrack.cc = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ }
+/* None of them matched. */
+if (common->leave != NULL)
+ set_jumps(common->leave, LABEL());
+
+OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
+jump = JUMP(SLJIT_JUMP);
+
+set_jumps(common->accept, LABEL());
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head);
+if (needsframe)
+ {
+ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
+ }
+OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
+
+JUMPHERE(jump);
+copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize);
+free_stack(common, localsize + framesize + alternativesize);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
+OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
+sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
+
+common->leavelabel = save_leavelabel;
+common->leave = save_leave;
+}
+
+#undef COMPILE_BACKTRACKPATH
+#undef CURRENT_AS
+
+void
+PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
+{
+struct sljit_compiler *compiler;
+backtrack_common rootbacktrack;
+compiler_common common_data;
+compiler_common *common = &common_data;
+const pcre_uint8 *tables = re->tables;
+pcre_study_data *study;
+int localsize;
+pcre_uchar *ccend;
+executable_functions *functions;
+void *executable_func;
+sljit_uw executable_size;
+struct sljit_label *mainloop = NULL;
+struct sljit_label *empty_match_found;
+struct sljit_label *empty_match_backtrack;
+struct sljit_jump *jump;
+struct sljit_jump *reqbyte_notfound = NULL;
+struct sljit_jump *empty_match;
+
+SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
+study = extra->study_data;
+
+if (!tables)
+ tables = PRIV(default_tables);
+
+memset(&rootbacktrack, 0, sizeof(backtrack_common));
+memset(common, 0, sizeof(compiler_common));
+rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
+
+common->start = rootbacktrack.cc;
+common->fcc = tables + fcc_offset;
+common->lcc = (sljit_w)(tables + lcc_offset);
+common->mode = mode;
+common->nltype = NLTYPE_FIXED;
+switch(re->options & PCRE_NEWLINE_BITS)
+ {
+ case 0:
+ /* Compile-time default */
+ switch (NEWLINE)
+ {
+ case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
+ case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
+ default: common->newline = NEWLINE; break;
+ }
+ break;
+ case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
+ case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
+ case PCRE_NEWLINE_CR+
+ PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;
+ case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
+ case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
+ default: return;
+ }
+if ((re->options & PCRE_BSR_ANYCRLF) != 0)
+ common->bsr_nltype = NLTYPE_ANYCRLF;
+else if ((re->options & PCRE_BSR_UNICODE) != 0)
+ common->bsr_nltype = NLTYPE_ANY;
+else
+ {
+#ifdef BSR_ANYCRLF
+ common->bsr_nltype = NLTYPE_ANYCRLF;
+#else
+ common->bsr_nltype = NLTYPE_ANY;
+#endif
+ }
+common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
+common->ctypes = (sljit_w)(tables + ctypes_offset);
+common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
+common->name_count = re->name_count;
+common->name_entry_size = re->name_entry_size;
+common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
+#ifdef SUPPORT_UTF
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+common->utf = (re->options & PCRE_UTF8) != 0;
+#ifdef SUPPORT_UCP
+common->use_ucp = (re->options & PCRE_UCP) != 0;
+#endif
+#endif /* SUPPORT_UTF */
+ccend = bracketend(rootbacktrack.cc);
+
+/* Calculate the local space size on the stack. */
+common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
+
+SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
+localsize = get_localspace(common, rootbacktrack.cc, ccend);
+if (localsize < 0)
+ return;
+
+/* Checking flags and updating ovector_start. */
+if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
+ {
+ common->req_char_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_w);
+ }
+if (mode != JIT_COMPILE)
+ {
+ common->start_used_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_w);
+ if (mode == JIT_PARTIAL_SOFT_COMPILE)
+ {
+ common->hit_start = common->ovector_start;
+ common->ovector_start += sizeof(sljit_w);
+ }
+ }
+if ((re->options & PCRE_FIRSTLINE) != 0)
+ {
+ common->first_line_end = common->ovector_start;
+ common->ovector_start += sizeof(sljit_w);
+ }
+
+/* Aligning ovector to even number of sljit words. */
+if ((common->ovector_start & sizeof(sljit_w)) != 0)
+ common->ovector_start += sizeof(sljit_w);
+
+SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
+common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
+localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
+if (localsize > SLJIT_MAX_LOCAL_SIZE)
+ return;
+common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
+if (!common->localptrs)
+ return;
+memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
+set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
+
+compiler = sljit_create_compiler();
+if (!compiler)
+ {
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+common->compiler = compiler;
+
+/* Main pcre_jit_exec entry. */
+sljit_emit_enter(compiler, 1, 5, 5, localsize);
+
+/* Register init. */
+reset_ovector(common, (re->top_bracket + 1) * 2);
+if (common->req_char_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0);
+
+OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
+
+if (mode == JIT_PARTIAL_SOFT_COMPILE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
+
+/* Main part of the matching */
+if ((re->options & PCRE_ANCHORED) == 0)
+ {
+ mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
+ /* Forward search if possible. */
+ if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
+ {
+ if ((re->flags & PCRE_FIRSTSET) != 0)
+ fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
+ else if ((re->flags & PCRE_STARTLINE) != 0)
+ fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
+ else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
+ fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
+ }
+ }
+if (common->req_char_ptr != 0)
+ reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
+
+/* Store the current STR_PTR in OVECTOR(0). */
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
+/* Copy the limit of allowed recursions. */
+OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
+if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
+/* Copy the beginning of the string. */
+if (mode == JIT_PARTIAL_SOFT_COMPILE)
+ {
+ jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
+ JUMPHERE(jump);
+ }
+else if (mode == JIT_PARTIAL_HARD_COMPILE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
+
+compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+
+empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+empty_match_found = LABEL();
+
+common->acceptlabel = LABEL();
+if (common->accept != NULL)
+ set_jumps(common->accept, common->acceptlabel);
+
+/* This means we have a match. Update the ovector. */
+copy_ovector(common, re->top_bracket + 1);
+common->leavelabel = LABEL();
+if (common->leave != NULL)
+ set_jumps(common->leave, common->leavelabel);
+sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
+
+if (mode != JIT_COMPILE)
+ {
+ common->partialmatchlabel = LABEL();
+ set_jumps(common->partialmatch, common->partialmatchlabel);
+ return_with_partial_match(common, common->leavelabel);
+ }
+
+empty_match_backtrack = LABEL();
+compile_backtrackpath(common, rootbacktrack.top);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+
+SLJIT_ASSERT(rootbacktrack.prev == NULL);
+
+if (mode == JIT_PARTIAL_SOFT_COMPILE)
+ {
+ /* Update hit_start only in the first time. */
+ jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
+ JUMPHERE(jump);
+ }
+
+/* Check we have remaining characters. */
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+
+if ((re->options & PCRE_ANCHORED) == 0)
+ {
+ if ((re->options & PCRE_FIRSTLINE) == 0)
+ {
+ if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
+ {
+ OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
+ CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
+ }
+ else
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
+ }
+ else
+ {
+ SLJIT_ASSERT(common->first_line_end != 0);
+ if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
+ {
+ OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL);
+ JUMPTO(SLJIT_C_ZERO, mainloop);
+ }
+ else
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop);
+ }
+ }
+
+/* No more remaining characters. */
+if (reqbyte_notfound != NULL)
+ JUMPHERE(reqbyte_notfound);
+
+if (mode == JIT_PARTIAL_SOFT_COMPILE)
+ CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
+
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
+JUMPTO(SLJIT_JUMP, common->leavelabel);
+
+flush_stubs(common);
+
+JUMPHERE(empty_match);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
+CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
+CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);
+JUMPTO(SLJIT_JUMP, empty_match_backtrack);
+
+common->currententry = common->entries;
+while (common->currententry != NULL)
+ {
+ /* Might add new entries. */
+ compile_recurse(common);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+ flush_stubs(common);
+ common->currententry = common->currententry->next;
+ }
+
+/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
+/* This is a (really) rare case. */
+set_jumps(common->stackalloc, LABEL());
+/* RETURN_ADDR is not a saved register. */
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
+OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
+
+sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
+jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+
+/* Allocation failed. */
+JUMPHERE(jump);
+/* We break the return address cache here, but this is a really rare case. */
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
+JUMPTO(SLJIT_JUMP, common->leavelabel);
+
+/* Call limit reached. */
+set_jumps(common->calllimit, LABEL());
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
+JUMPTO(SLJIT_JUMP, common->leavelabel);
+
+if (common->revertframes != NULL)
+ {
+ set_jumps(common->revertframes, LABEL());
+ do_revertframes(common);
+ }
+if (common->wordboundary != NULL)
+ {
+ set_jumps(common->wordboundary, LABEL());
+ check_wordboundary(common);
+ }
+if (common->anynewline != NULL)
+ {
+ set_jumps(common->anynewline, LABEL());
+ check_anynewline(common);
+ }
+if (common->hspace != NULL)
+ {
+ set_jumps(common->hspace, LABEL());
+ check_hspace(common);
+ }
+if (common->vspace != NULL)
+ {
+ set_jumps(common->vspace, LABEL());
+ check_vspace(common);
+ }
+if (common->casefulcmp != NULL)
+ {
+ set_jumps(common->casefulcmp, LABEL());
+ do_casefulcmp(common);
+ }
+if (common->caselesscmp != NULL)
+ {
+ set_jumps(common->caselesscmp, LABEL());
+ do_caselesscmp(common);
+ }
+#ifdef SUPPORT_UTF
+if (common->utfreadchar != NULL)
+ {
+ set_jumps(common->utfreadchar, LABEL());
+ do_utfreadchar(common);
+ }
+#ifdef COMPILE_PCRE8
+if (common->utfreadtype8 != NULL)
+ {
+ set_jumps(common->utfreadtype8, LABEL());
+ do_utfreadtype8(common);
+ }
+#endif
+#endif /* COMPILE_PCRE8 */
+#ifdef SUPPORT_UCP
+if (common->getucd != NULL)
+ {
+ set_jumps(common->getucd, LABEL());
+ do_getucd(common);
+ }
+#endif
+
+SLJIT_FREE(common->localptrs);
+executable_func = sljit_generate_code(compiler);
+executable_size = sljit_get_generated_code_size(compiler);
+sljit_free_compiler(compiler);
+if (executable_func == NULL)
+ return;
+
+/* Reuse the function descriptor if possible. */
+if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
+ functions = (executable_functions *)extra->executable_jit;
+else
+ {
+ functions = SLJIT_MALLOC(sizeof(executable_functions));
+ if (functions == NULL)
+ {
+ /* This case is highly unlikely since we just recently
+ freed a lot of memory. Although not impossible. */
+ sljit_free_code(executable_func);
+ return;
+ }
+ memset(functions, 0, sizeof(executable_functions));
+ extra->executable_jit = functions;
+ extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
+ }
+
+functions->executable_funcs[mode] = executable_func;
+functions->executable_sizes[mode] = executable_size;
+}
+
+static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func)
+{
+union {
+ void* executable_func;
+ jit_function call_executable_func;
+} convert_executable_func;
+pcre_uint8 local_area[LOCAL_SPACE_SIZE];
+struct sljit_stack local_stack;
+
+local_stack.top = (sljit_w)&local_area;
+local_stack.base = local_stack.top;
+local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
+local_stack.max_limit = local_stack.limit;
+arguments->stack = &local_stack;
+convert_executable_func.executable_func = executable_func;
+return convert_executable_func.call_executable_func(arguments);
+}
+
+int
+PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject,
+ int length, int start_offset, int options, int *offsets, int offsetcount)
+{
+executable_functions *functions = (executable_functions *)extra_data->executable_jit;
+union {
+ void* executable_func;
+ jit_function call_executable_func;
+} convert_executable_func;
+jit_arguments arguments;
+int maxoffsetcount;
+int retval;
+int mode = JIT_COMPILE;
+
+if ((options & PCRE_PARTIAL_HARD) != 0)
+ mode = JIT_PARTIAL_HARD_COMPILE;
+else if ((options & PCRE_PARTIAL_SOFT) != 0)
+ mode = JIT_PARTIAL_SOFT_COMPILE;
+
+if (functions->executable_funcs[mode] == NULL)
+ return PCRE_ERROR_NULL;
+
+/* Sanity checks should be handled by pcre_exec. */
+arguments.stack = NULL;
+arguments.str = subject + start_offset;
+arguments.begin = subject;
+arguments.end = subject + length;
+arguments.mark_ptr = NULL;
+/* JIT decreases this value less frequently than the interpreter. */
+arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
+arguments.notbol = (options & PCRE_NOTBOL) != 0;
+arguments.noteol = (options & PCRE_NOTEOL) != 0;
+arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
+arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
+arguments.offsets = offsets;
+
+/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of
+the output vector for storing captured strings, with the remainder used as
+workspace. We don't need the workspace here. For compatibility, we limit the
+number of captured strings in the same way as pcre_exec(), so that the user
+gets the same result with and without JIT. */
+
+if (offsetcount != 2)
+ offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
+maxoffsetcount = (re->top_bracket + 1) * 2;
+if (offsetcount > maxoffsetcount)
+ offsetcount = maxoffsetcount;
+arguments.offsetcount = offsetcount;
+
+if (functions->callback)
+ arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
+else
+ arguments.stack = (struct sljit_stack *)functions->userdata;
+
+if (arguments.stack == NULL)
+ retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]);
+else
+ {
+ convert_executable_func.executable_func = functions->executable_funcs[mode];
+ retval = convert_executable_func.call_executable_func(&arguments);
+ }
+
+if (retval * 2 > offsetcount)
+ retval = 0;
+if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
+ *(extra_data->mark) = arguments.mark_ptr;
+
+return retval;
+}
+
+void
+PRIV(jit_free)(void *executable_funcs)
+{
+int i;
+executable_functions *functions = (executable_functions *)executable_funcs;
+for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
+ {
+ if (functions->executable_funcs[i] != NULL)
+ sljit_free_code(functions->executable_funcs[i]);
+ }
+SLJIT_FREE(functions);
+}
+
+int
+PRIV(jit_get_size)(void *executable_funcs)
+{
+int i;
+sljit_uw size = 0;
+sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes;
+for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
+ size += executable_sizes[i];
+return (int)size;
+}
+
+const char*
+PRIV(jit_get_target)(void)
+{
+return sljit_get_platform_name();
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL pcre_jit_stack *
+pcre_jit_stack_alloc(int startsize, int maxsize)
+#else
+PCRE_EXP_DECL pcre16_jit_stack *
+pcre16_jit_stack_alloc(int startsize, int maxsize)
+#endif
+{
+if (startsize < 1 || maxsize < 1)
+ return NULL;
+if (startsize > maxsize)
+ startsize = maxsize;
+startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
+maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
+return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_jit_stack_free(pcre_jit_stack *stack)
+#else
+PCRE_EXP_DECL void
+pcre16_jit_stack_free(pcre16_jit_stack *stack)
+#endif
+{
+sljit_free_stack((struct sljit_stack *)stack);
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
+#else
+PCRE_EXP_DECL void
+pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
+#endif
+{
+executable_functions *functions;
+if (extra != NULL &&
+ (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra->executable_jit != NULL)
+ {
+ functions = (executable_functions *)extra->executable_jit;
+ functions->callback = callback;
+ functions->userdata = userdata;
+ }
+}
+
+#else /* SUPPORT_JIT */
+
+/* These are dummy functions to avoid linking errors when JIT support is not
+being compiled. */
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL pcre_jit_stack *
+pcre_jit_stack_alloc(int startsize, int maxsize)
+#else
+PCRE_EXP_DECL pcre16_jit_stack *
+pcre16_jit_stack_alloc(int startsize, int maxsize)
+#endif
+{
+(void)startsize;
+(void)maxsize;
+return NULL;
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_jit_stack_free(pcre_jit_stack *stack)
+#else
+PCRE_EXP_DECL void
+pcre16_jit_stack_free(pcre16_jit_stack *stack)
+#endif
+{
+(void)stack;
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
+#else
+PCRE_EXP_DECL void
+pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
+#endif
+{
+(void)extra;
+(void)callback;
+(void)userdata;
+}
+
+#endif
+
+/* End of pcre_jit_compile.c */
diff -Nru pcre3-8.12/pcre_jit_test.c pcre3-8.31/pcre_jit_test.c
--- pcre3-8.12/pcre_jit_test.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre_jit_test.c 2012-06-17 16:04:44.000000000 +0000
@@ -0,0 +1,1279 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Main Library written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+ This JIT compiler regression test program was written by Zoltan Herczeg
+ Copyright (c) 2010-2012
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+#include "pcre.h"
+
+#define PCRE_BUG 0x80000000
+
+/*
+ Letter characters:
+ \xe6\x92\xad = 0x64ad = 25773 (kanji)
+ Non-letter characters:
+ \xc2\xa1 = 0xa1 = (Inverted Exclamation Mark)
+ \xf3\xa9\xb7\x80 = 0xe9dc0 = 957888
+ \xed\xa0\x80 = 55296 = 0xd800 (Invalid UTF character)
+ \xed\xb0\x80 = 56320 = 0xdc00 (Invalid UTF character)
+ Newlines:
+ \xc2\x85 = 0x85 = 133 (NExt Line = NEL)
+ \xe2\x80\xa8 = 0x2028 = 8232 (Line Separator)
+ Othercase pairs:
+ \xc3\xa9 = 0xe9 = 233 (e')
+ \xc3\x89 = 0xc9 = 201 (E')
+ \xc3\xa1 = 0xe1 = 225 (a')
+ \xc3\x81 = 0xc1 = 193 (A')
+ \xc8\xba = 0x23a = 570
+ \xe2\xb1\xa5 = 0x2c65 = 11365
+ \xe1\xbd\xb8 = 0x1f78 = 8056
+ \xe1\xbf\xb8 = 0x1ff8 = 8184
+ \xf0\x90\x90\x80 = 0x10400 = 66560
+ \xf0\x90\x90\xa8 = 0x10428 = 66600
+ Mark property:
+ \xcc\x8d = 0x30d = 781
+ Special:
+ \xdf\xbf = 0x7ff = 2047 (highest 2 byte character)
+ \xe0\xa0\x80 = 0x800 = 2048 (lowest 2 byte character)
+ \xef\xbf\xbf = 0xffff = 65535 (highest 3 byte character)
+ \xf0\x90\x80\x80 = 0x10000 = 65536 (lowest 4 byte character)
+ \xf4\x8f\xbf\xbf = 0x10ffff = 1114111 (highest allowed utf character)
+*/
+
+static int regression_tests(void);
+
+int main(void)
+{
+ int jit = 0;
+#ifdef SUPPORT_PCRE8
+ pcre_config(PCRE_CONFIG_JIT, &jit);
+#else
+ pcre16_config(PCRE_CONFIG_JIT, &jit);
+#endif
+ if (!jit) {
+ printf("JIT must be enabled to run pcre_jit_test\n");
+ return 1;
+ }
+ return regression_tests();
+}
+
+/* --------------------------------------------------------------------------------------- */
+
+#if !(defined SUPPORT_PCRE8) && !(defined SUPPORT_PCRE16)
+#error SUPPORT_PCRE8 or SUPPORT_PCRE16 must be defined
+#endif
+
+#define MUA (PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF)
+#define MUAP (PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF | PCRE_UCP)
+#define CMUA (PCRE_CASELESS | PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF)
+#define CMUAP (PCRE_CASELESS | PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF | PCRE_UCP)
+#define MA (PCRE_MULTILINE | PCRE_NEWLINE_ANYCRLF)
+#define MAP (PCRE_MULTILINE | PCRE_NEWLINE_ANYCRLF | PCRE_UCP)
+#define CMA (PCRE_CASELESS | PCRE_MULTILINE | PCRE_NEWLINE_ANYCRLF)
+
+#define OFFSET_MASK 0x00ffff
+#define F_NO8 0x010000
+#define F_NO16 0x020000
+#define F_NOMATCH 0x040000
+#define F_DIFF 0x080000
+#define F_FORCECONV 0x100000
+#define F_PROPERTY 0x200000
+
+struct regression_test_case {
+ int flags;
+ int start_offset;
+ const char *pattern;
+ const char *input;
+};
+
+static struct regression_test_case regression_test_cases[] = {
+ /* Constant strings. */
+ { MUA, 0, "AbC", "AbAbC" },
+ { MUA, 0, "ACCEPT", "AACACCACCEACCEPACCEPTACCEPTT" },
+ { CMUA, 0, "aA#\xc3\xa9\xc3\x81", "aA#Aa#\xc3\x89\xc3\xa1" },
+ { MA, 0, "[^a]", "aAbB" },
+ { CMA, 0, "[^m]", "mMnN" },
+ { MA, 0, "a[^b][^#]", "abacd" },
+ { CMA, 0, "A[^B][^E]", "abacd" },
+ { CMUA, 0, "[^x][^#]", "XxBll" },
+ { MUA, 0, "[^a]", "aaa\xc3\xa1#Ab" },
+ { CMUA, 0, "[^A]", "aA\xe6\x92\xad" },
+ { MUA, 0, "\\W(\\W)?\\w", "\r\n+bc" },
+ { MUA, 0, "\\W(\\W)?\\w", "\n\r+bc" },
+ { MUA, 0, "\\W(\\W)?\\w", "\r\r+bc" },
+ { MUA, 0, "\\W(\\W)?\\w", "\n\n+bc" },
+ { MUA, 0, "[axd]", "sAXd" },
+ { CMUA, 0, "[axd]", "sAXd" },
+ { CMUA, 0 | F_NOMATCH, "[^axd]", "DxA" },
+ { MUA, 0, "[a-dA-C]", "\xe6\x92\xad\xc3\xa9.B" },
+ { MUA, 0, "[^a-dA-C]", "\xe6\x92\xad\xc3\xa9" },
+ { CMUA, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." },
+ { MUA, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." },
+ { MUA, 0, "[^a]", "\xc2\x80[]" },
+ { CMUA, 0, "\xf0\x90\x90\xa7", "\xf0\x90\x91\x8f" },
+ { CMA, 0, "1a2b3c4", "1a2B3c51A2B3C4" },
+ { PCRE_CASELESS, 0, "\xff#a", "\xff#\xff\xfe##\xff#A" },
+ { PCRE_CASELESS, 0, "\xfe", "\xff\xfc#\xfe\xfe" },
+ { PCRE_CASELESS, 0, "a1", "Aa1" },
+ { MA, 0, "\\Ca", "cda" },
+ { CMA, 0, "\\Ca", "CDA" },
+ { MA, 0 | F_NOMATCH, "\\Cx", "cda" },
+ { CMA, 0 | F_NOMATCH, "\\Cx", "CDA" },
+ { CMUAP, 0, "\xf0\x90\x90\x80\xf0\x90\x90\xa8", "\xf0\x90\x90\xa8\xf0\x90\x90\x80" },
+ { CMUAP, 0, "\xf0\x90\x90\x80{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" },
+ { CMUAP, 0, "\xf0\x90\x90\xa8{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" },
+ { CMUAP, 0, "\xe1\xbd\xb8\xe1\xbf\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" },
+
+ /* Assertions. */
+ { MUA, 0, "\\b[^A]", "A_B#" },
+ { MA, 0 | F_NOMATCH, "\\b\\W", "\n*" },
+ { MUA, 0, "\\B[^,]\\b[^s]\\b", "#X" },
+ { MAP, 0, "\\B", "_\xa1" },
+ { MAP, 0, "\\b_\\b[,A]\\B", "_," },
+ { MUAP, 0, "\\b", "\xe6\x92\xad!" },
+ { MUAP, 0, "\\B", "_\xc2\xa1\xc3\xa1\xc2\x85" },
+ { MUAP, 0, "\\b[^A]\\B[^c]\\b[^_]\\B", "_\xc3\xa1\xe2\x80\xa8" },
+ { MUAP, 0, "\\b\\w+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" },
+ { MUA, 0 | F_NOMATCH, "\\b.", "\xcd\xbe" },
+ { CMUAP, 0, "\\By", "\xf0\x90\x90\xa8y" },
+ { MA, 0 | F_NOMATCH, "\\R^", "\n" },
+ { MA, 1 | F_NOMATCH, "^", "\n" },
+ { 0, 0, "^ab", "ab" },
+ { 0, 0 | F_NOMATCH, "^ab", "aab" },
+ { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "^a", "\r\raa\n\naa\r\naa" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF, 0, "^-", "\xe2\x80\xa8--\xc2\x85-\r\n-" },
+ { PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "^-", "a--b--\x85--" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY, 0, "^-", "a--\xe2\x80\xa8--" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY, 0, "^-", "a--\xc2\x85--" },
+ { 0, 0, "ab$", "ab" },
+ { 0, 0 | F_NOMATCH, "ab$", "abab\n\n" },
+ { PCRE_DOLLAR_ENDONLY, 0 | F_NOMATCH, "ab$", "abab\r\n" },
+ { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "a$", "\r\raa\n\naa\r\naa" },
+ { PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "a$", "aaa" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANYCRLF, 0, "#$", "#\xc2\x85###\r#" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY, 0, "#$", "#\xe2\x80\xa9" },
+ { PCRE_NOTBOL | PCRE_NEWLINE_ANY, 0 | F_NOMATCH, "^a", "aa\naa" },
+ { PCRE_NOTBOL | PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "^a", "aa\naa" },
+ { PCRE_NOTEOL | PCRE_NEWLINE_ANY, 0 | F_NOMATCH, "a$", "aa\naa" },
+ { PCRE_NOTEOL | PCRE_NEWLINE_ANY, 0 | F_NOMATCH, "a$", "aa\r\n" },
+ { PCRE_UTF8 | PCRE_DOLLAR_ENDONLY | PCRE_NEWLINE_ANY, 0 | F_PROPERTY, "\\p{Any}{2,}$", "aa\r\n" },
+ { PCRE_NOTEOL | PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0, "a$", "aa\naa" },
+ { PCRE_NEWLINE_CR, 0, ".\\Z", "aaa" },
+ { PCRE_NEWLINE_CR | PCRE_UTF8, 0, "a\\Z", "aaa\r" },
+ { PCRE_NEWLINE_CR, 0, ".\\Z", "aaa\n" },
+ { PCRE_NEWLINE_CRLF, 0, ".\\Z", "aaa\r" },
+ { PCRE_NEWLINE_CRLF | PCRE_UTF8, 0, ".\\Z", "aaa\n" },
+ { PCRE_NEWLINE_CRLF, 0, ".\\Z", "aaa\r\n" },
+ { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa" },
+ { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r" },
+ { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\n" },
+ { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r\n" },
+ { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\xe2\x80\xa8" },
+ { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa" },
+ { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r" },
+ { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\n" },
+ { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".\\Z", "aaa\r\n" },
+ { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, ".\\Z", "aaa\xc2\x85" },
+ { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, ".\\Z", "aaa\xe2\x80\xa8" },
+ { MA, 0, "\\Aa", "aaa" },
+ { MA, 1 | F_NOMATCH, "\\Aa", "aaa" },
+ { MA, 1, "\\Ga", "aaa" },
+ { MA, 1 | F_NOMATCH, "\\Ga", "aba" },
+ { MA, 0, "a\\z", "aaa" },
+ { MA, 0 | F_NOMATCH, "a\\z", "aab" },
+
+ /* Brackets. */
+ { MUA, 0, "(ab|bb|cd)", "bacde" },
+ { MUA, 0, "(?:ab|a)(bc|c)", "ababc" },
+ { MUA, 0, "((ab|(cc))|(bb)|(?:cd|efg))", "abac" },
+ { CMUA, 0, "((aB|(Cc))|(bB)|(?:cd|EFg))", "AcCe" },
+ { MUA, 0, "((ab|(cc))|(bb)|(?:cd|ebg))", "acebebg" },
+ { MUA, 0, "(?:(a)|(?:b))(cc|(?:d|e))(a|b)k", "accabdbbccbk" },
+
+ /* Greedy and non-greedy ? operators. */
+ { MUA, 0, "(?:a)?a", "laab" },
+ { CMUA, 0, "(A)?A", "llaab" },
+ { MUA, 0, "(a)?\?a", "aab" }, /* ?? is the prefix of trygraphs in GCC. */
+ { MUA, 0, "(a)?a", "manm" },
+ { CMUA, 0, "(a|b)?\?d((?:e)?)", "ABABdx" },
+ { MUA, 0, "(a|b)?\?d((?:e)?)", "abcde" },
+ { MUA, 0, "((?:ab)?\?g|b(?:g(nn|d)?\?)?)?\?(?:n)?m", "abgnbgnnbgdnmm" },
+
+ /* Greedy and non-greedy + operators */
+ { MUA, 0, "(aa)+aa", "aaaaaaa" },
+ { MUA, 0, "(aa)+?aa", "aaaaaaa" },
+ { MUA, 0, "(?:aba|ab|a)+l", "ababamababal" },
+ { MUA, 0, "(?:aba|ab|a)+?l", "ababamababal" },
+ { MUA, 0, "(a(?:bc|cb|b|c)+?|ss)+e", "accssabccbcacbccbbXaccssabccbcacbccbbe" },
+ { MUA, 0, "(a(?:bc|cb|b|c)+|ss)+?e", "accssabccbcacbccbbXaccssabccbcacbccbbe" },
+ { MUA, 0, "(?:(b(c)+?)+)?\?(?:(bc)+|(cb)+)+(?:m)+", "bccbcccbcbccbcbPbccbcccbcbccbcbmmn" },
+
+ /* Greedy and non-greedy * operators */
+ { CMUA, 0, "(?:AA)*AB", "aaaaaaamaaaaaaab" },
+ { MUA, 0, "(?:aa)*?ab", "aaaaaaamaaaaaaab" },
+ { MUA, 0, "(aa|ab)*ab", "aaabaaab" },
+ { CMUA, 0, "(aa|Ab)*?aB", "aaabaaab" },
+ { MUA, 0, "(a|b)*(?:a)*(?:b)*m", "abbbaaababanabbbaaababamm" },
+ { MUA, 0, "(a|b)*?(?:a)*?(?:b)*?m", "abbbaaababanabbbaaababamm" },
+ { MA, 0, "a(a(\\1*)a|(b)b+){0}a", "aa" },
+ { MA, 0, "((?:a|)*){0}a", "a" },
+
+ /* Combining ? + * operators */
+ { MUA, 0, "((bm)+)?\?(?:a)*(bm)+n|((am)+?)?(?:a)+(am)*n", "bmbmabmamaaamambmaman" },
+ { MUA, 0, "(((ab)?cd)*ef)+g", "abcdcdefcdefefmabcdcdefcdefefgg" },
+ { MUA, 0, "(((ab)?\?cd)*?ef)+?g", "abcdcdefcdefefmabcdcdefcdefefgg" },
+ { MUA, 0, "(?:(ab)?c|(?:ab)+?d)*g", "ababcdccababddg" },
+ { MUA, 0, "(?:(?:ab)?\?c|(ab)+d)*?g", "ababcdccababddg" },
+
+ /* Single character iterators. */
+ { MUA, 0, "(a+aab)+aaaab", "aaaabcaaaabaabcaabcaaabaaaab" },
+ { MUA, 0, "(a*a*aab)+x", "aaaaabaabaaabmaabx" },
+ { MUA, 0, "(a*?(b|ab)a*?)+x", "aaaabcxbbaabaacbaaabaabax" },
+ { MUA, 0, "(a+(ab|ad)a+)+x", "aaabaaaadaabaaabaaaadaaax" },
+ { MUA, 0, "(a?(a)a?)+(aaa)", "abaaabaaaaaaaa" },
+ { MUA, 0, "(a?\?(a)a?\?)+(b)", "aaaacaaacaacacbaaab" },
+ { MUA, 0, "(a{0,4}(b))+d", "aaaaaabaabcaaaaabaaaaabd" },
+ { MUA, 0, "(a{0,4}?[^b])+d+(a{0,4}[^b])d+", "aaaaadaaaacaadddaaddd" },
+ { MUA, 0, "(ba{2})+c", "baabaaabacbaabaac" },
+ { MUA, 0, "(a*+bc++)+", "aaabbcaaabcccab" },
+ { MUA, 0, "(a?+[^b])+", "babaacacb" },
+ { MUA, 0, "(a{0,3}+b)(a{0,3}+b)(a{0,3}+)[^c]", "abaabaaacbaabaaaac" },
+ { CMUA, 0, "([a-c]+[d-f]+?)+?g", "aBdacdehAbDaFgA" },
+ { CMUA, 0, "[c-f]+k", "DemmFke" },
+ { MUA, 0, "([DGH]{0,4}M)+", "GGDGHDGMMHMDHHGHM" },
+ { MUA, 0, "([a-c]{4,}s)+", "abasabbasbbaabsbba" },
+ { CMUA, 0, "[ace]{3,7}", "AcbDAcEEcEd" },
+ { CMUA, 0, "[ace]{3,7}?", "AcbDAcEEcEd" },
+ { CMUA, 0, "[ace]{3,}", "AcbDAcEEcEd" },
+ { CMUA, 0, "[ace]{3,}?", "AcbDAcEEcEd" },
+ { MUA, 0, "[ckl]{2,}?g", "cdkkmlglglkcg" },
+ { CMUA, 0, "[ace]{5}?", "AcCebDAcEEcEd" },
+ { MUA, 0, "([AbC]{3,5}?d)+", "BACaAbbAEAACCbdCCbdCCAAbb" },
+ { MUA, 0, "([^ab]{0,}s){2}", "abaabcdsABamsDDs" },
+ { MUA, 0, "\\b\\w+\\B", "x,a_cd" },
+ { MUAP, 0, "\\b[^\xc2\xa1]+\\B", "\xc3\x89\xc2\xa1\xe6\x92\xad\xc3\x81\xc3\xa1" },
+ { CMUA, 0, "[^b]+(a*)([^c]?d{3})", "aaaaddd" },
+ { CMUAP, 0, "\xe1\xbd\xb8{2}", "\xe1\xbf\xb8#\xe1\xbf\xb8\xe1\xbd\xb8" },
+ { CMUA, 0, "[^\xf0\x90\x90\x80]{2,4}@", "\xf0\x90\x90\xa8\xf0\x90\x90\x80###\xf0\x90\x90\x80@@@" },
+ { CMUA, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" },
+ { MUA, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" },
+ { MUA, 0, "[^\xe1\xbd\xb8]{3,}?", "##\xe1\xbd\xb8#\xe1\xbd\xb8#\xc3\x89#\xe1\xbd\xb8" },
+
+ /* Basic character sets. */
+ { MUA, 0, "(?:\\s)+(?:\\S)+", "ab \t\xc3\xa9\xe6\x92\xad " },
+ { MUA, 0, "(\\w)*(k)(\\W)?\?", "abcdef abck11" },
+ { MUA, 0, "\\((\\d)+\\)\\D", "a() (83 (8)2 (9)ab" },
+ { MUA, 0, "\\w(\\s|(?:\\d)*,)+\\w\\wb", "a 5, 4,, bb 5, 4,, aab" },
+ { MUA, 0, "(\\v+)(\\V+)", "\x0e\xc2\x85\xe2\x80\xa8\x0b\x09\xe2\x80\xa9" },
+ { MUA, 0, "(\\h+)(\\H+)", "\xe2\x80\xa8\xe2\x80\x80\x20\xe2\x80\x8a\xe2\x81\x9f\xe3\x80\x80\x09\x20\xc2\xa0\x0a" },
+
+ /* Unicode properties. */
+ { MUAP, 0, "[1-5\xc3\xa9\\w]", "\xc3\xa1_" },
+ { MUAP, 0 | F_PROPERTY, "[\xc3\x81\\p{Ll}]", "A_\xc3\x89\xc3\xa1" },
+ { MUAP, 0, "[\\Wd-h_x-z]+", "a\xc2\xa1#_yhzdxi" },
+ { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}]", "abc" },
+ { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}]", "abc" },
+ { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[\\P{Any}\xc3\xa1-\xc3\xa8]", "abc" },
+ { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[^\\p{Any}\xc3\xa1-\xc3\xa8]", "abc" },
+ { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" },
+ { MUAP, 0 | F_NOMATCH | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" },
+ { MUAP, 0 | F_PROPERTY, "[\xc3\xa1-\xc3\xa8\\p{Any}]", "abc" },
+ { MUAP, 0 | F_PROPERTY, "[^\xc3\xa1-\xc3\xa8\\P{Any}]", "abc" },
+ { MUAP, 0, "[b-\xc3\xa9\\s]", "a\xc\xe6\x92\xad" },
+ { CMUAP, 0, "[\xc2\x85-\xc2\x89\xc3\x89]", "\xc2\x84\xc3\xa9" },
+ { MUAP, 0, "[^b-d^&\\s]{3,}", "db^ !a\xe2\x80\xa8_ae" },
+ { MUAP, 0 | F_PROPERTY, "[^\\S\\P{Any}][\\sN]{1,3}[\\P{N}]{4}", "\xe2\x80\xaa\xa N\x9\xc3\xa9_0" },
+ { MUA, 0 | F_PROPERTY, "[^\\P{L}\x9!D-F\xa]{2,3}", "\x9,.DF\xa.CG\xc3\x81" },
+ { CMUAP, 0, "[\xc3\xa1-\xc3\xa9_\xe2\x80\xa0-\xe2\x80\xaf]{1,5}[^\xe2\x80\xa0-\xe2\x80\xaf]", "\xc2\xa1\xc3\x89\xc3\x89\xe2\x80\xaf_\xe2\x80\xa0" },
+ { MUAP, 0 | F_PROPERTY, "[\xc3\xa2-\xc3\xa6\xc3\x81-\xc3\x84\xe2\x80\xa8-\xe2\x80\xa9\xe6\x92\xad\\p{Zs}]{2,}", "\xe2\x80\xa7\xe2\x80\xa9\xe6\x92\xad \xe6\x92\xae" },
+ { MUAP, 0 | F_PROPERTY, "[\\P{L&}]{2}[^\xc2\x85-\xc2\x89\\p{Ll}\\p{Lu}]{2}", "\xc3\xa9\xe6\x92\xad.a\xe6\x92\xad|\xc2\x8a#" },
+ { PCRE_UCP, 0, "[a-b\\s]{2,5}[^a]", "AB baaa" },
+
+ /* Possible empty brackets. */
+ { MUA, 0, "(?:|ab||bc|a)+d", "abcxabcabd" },
+ { MUA, 0, "(|ab||bc|a)+d", "abcxabcabd" },
+ { MUA, 0, "(?:|ab||bc|a)*d", "abcxabcabd" },
+ { MUA, 0, "(|ab||bc|a)*d", "abcxabcabd" },
+ { MUA, 0, "(?:|ab||bc|a)+?d", "abcxabcabd" },
+ { MUA, 0, "(|ab||bc|a)+?d", "abcxabcabd" },
+ { MUA, 0, "(?:|ab||bc|a)*?d", "abcxabcabd" },
+ { MUA, 0, "(|ab||bc|a)*?d", "abcxabcabd" },
+ { MUA, 0, "(((a)*?|(?:ba)+)+?|(?:|c|ca)*)*m", "abaacaccabacabalabaacaccabacabamm" },
+ { MUA, 0, "(?:((?:a)*|(ba)+?)+|(|c|ca)*?)*?m", "abaacaccabacabalabaacaccabacabamm" },
+
+ /* Start offset. */
+ { MUA, 3, "(\\d|(?:\\w)*\\w)+", "0ac01Hb" },
+ { MUA, 4 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" },
+ { MUA, 2 | F_NOMATCH, "(\\w\\W\\w)+", "ab#d" },
+ { MUA, 1, "(\\w\\W\\w)+", "ab#d" },
+
+ /* Newline. */
+ { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "\\W{0,2}[^#]{3}", "\r\n#....." },
+ { PCRE_MULTILINE | PCRE_NEWLINE_CR, 0, "\\W{0,2}[^#]{3}", "\r\n#....." },
+ { PCRE_MULTILINE | PCRE_NEWLINE_CRLF, 0, "\\W{1,3}[^#]", "\r\n##...." },
+
+ /* Any character except newline or any newline. */
+ { PCRE_NEWLINE_CRLF, 0, ".", "\r" },
+ { PCRE_NEWLINE_CRLF | PCRE_UTF8, 0, ".(.).", "a\xc3\xa1\r\n\n\r\r" },
+ { PCRE_NEWLINE_ANYCRLF, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" },
+ { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0, ".(.)", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa8" },
+ { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, "(.).", "a\rb\nc\r\n\xc2\x85\xe2\x80\xa9$de" },
+ { PCRE_NEWLINE_ANYCRLF | PCRE_UTF8, 0 | F_NOMATCH, ".(.).", "\xe2\x80\xa8\nb\r" },
+ { PCRE_NEWLINE_ANY, 0, "(.)(.)", "#\x85#\r#\n#\r\n#\x84" },
+ { PCRE_NEWLINE_ANY | PCRE_UTF8, 0, "(.+)#", "#\rMn\xc2\x85#\n###" },
+ { PCRE_BSR_ANYCRLF, 0, "\\R", "\r" },
+ { PCRE_BSR_ANYCRLF, 0, "\\R", "\x85#\r\n#" },
+ { PCRE_BSR_UNICODE | PCRE_UTF8, 0, "\\R", "ab\xe2\x80\xa8#c" },
+ { PCRE_BSR_UNICODE | PCRE_UTF8, 0, "\\R", "ab\r\nc" },
+ { PCRE_NEWLINE_CRLF | PCRE_BSR_UNICODE | PCRE_UTF8, 0, "(\\R.)+", "\xc2\x85\r\n#\xe2\x80\xa8\n\r\n\r" },
+ { MUA, 0 | F_NOMATCH, "\\R+", "ab" },
+ { MUA, 0, "\\R+", "ab\r\n\r" },
+ { MUA, 0, "\\R*", "ab\r\n\r" },
+ { MUA, 0, "\\R*", "\r\n\r" },
+ { MUA, 0, "\\R{2,4}", "\r\nab\r\r" },
+ { MUA, 0, "\\R{2,4}", "\r\nab\n\n\n\r\r\r" },
+ { MUA, 0, "\\R{2,}", "\r\nab\n\n\n\r\r\r" },
+ { MUA, 0, "\\R{0,3}", "\r\n\r\n\r\n\r\n\r\n" },
+ { MUA, 0 | F_NOMATCH, "\\R+\\R\\R", "\r\n\r\n" },
+ { MUA, 0, "\\R+\\R\\R", "\r\r\r" },
+ { MUA, 0, "\\R*\\R\\R", "\n\r" },
+ { MUA, 0 | F_NOMATCH, "\\R{2,4}\\R\\R", "\r\r\r" },
+ { MUA, 0, "\\R{2,4}\\R\\R", "\r\r\r\r" },
+
+ /* Atomic groups (no fallback from "next" direction). */
+ { MUA, 0 | F_NOMATCH, "(?>ab)ab", "bab" },
+ { MUA, 0 | F_NOMATCH, "(?>(ab))ab", "bab" },
+ { MUA, 0, "(?>ab)+abc(?>de)*def(?>gh)?ghe(?>ij)+?k(?>lm)*?n(?>op)?\?op",
+ "bababcdedefgheijijklmlmnop" },
+ { MUA, 0, "(?>a(b)+a|(ab)?\?(b))an", "abban" },
+ { MUA, 0, "(?>ab+a|(?:ab)?\?b)an", "abban" },
+ { MUA, 0, "((?>ab|ad|)*?)(?>|c)*abad", "abababcababad" },
+ { MUA, 0, "(?>(aa|b|)*+(?>(##)|###)*d|(aa)(?>(baa)?)m)", "aabaa#####da" },
+ { MUA, 0, "((?>a|)+?)b", "aaacaaab" },
+ { MUA, 0, "(?>x|)*$", "aaa" },
+ { MUA, 0, "(?>(x)|)*$", "aaa" },
+ { MUA, 0, "(?>x|())*$", "aaa" },
+ { MUA, 0, "((?>[cxy]a|[a-d])*?)b", "aaa+ aaab" },
+ { MUA, 0, "((?>[cxy](a)|[a-d])*?)b", "aaa+ aaab" },
+ { MUA, 0, "(?>((?>(a+))))bab|(?>((?>(a+))))bb", "aaaabaaabaabab" },
+ { MUA, 0, "(?>(?>a+))bab|(?>(?>a+))bb", "aaaabaaabaabab" },
+ { MUA, 0, "(?>(a)c|(?>(c)|(a))a)b*?bab", "aaaabaaabaabab" },
+ { MUA, 0, "(?>ac|(?>c|a)a)b*?bab", "aaaabaaabaabab" },
+ { MUA, 0, "(?>(b)b|(a))*b(?>(c)|d)?x", "ababcaaabdbx" },
+ { MUA, 0, "(?>bb|a)*b(?>c|d)?x", "ababcaaabdbx" },
+ { MUA, 0, "(?>(bb)|a)*b(?>c|(d))?x", "ababcaaabdbx" },
+ { MUA, 0, "(?>(a))*?(?>(a))+?(?>(a))??x", "aaaaaacccaaaaabax" },
+ { MUA, 0, "(?>a)*?(?>a)+?(?>a)??x", "aaaaaacccaaaaabax" },
+ { MUA, 0, "(?>(a)|)*?(?>(a)|)+?(?>(a)|)??x", "aaaaaacccaaaaabax" },
+ { MUA, 0, "(?>a|)*?(?>a|)+?(?>a|)??x", "aaaaaacccaaaaabax" },
+ { MUA, 0, "(?>a(?>(a{0,2}))*?b|aac)+b", "aaaaaaacaaaabaaaaacaaaabaacaaabb" },
+ { CMA, 0, "(?>((?>a{32}|b+|(a*))?(?>c+|d*)?\?)+e)+?f", "aaccebbdde bbdaaaccebbdee bbdaaaccebbdeef" },
+ { MUA, 0, "(?>(?:(?>aa|a||x)+?b|(?>aa|a||(x))+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" },
+ { MUA, 0, "(?>(?:(?>aa|a||(x))+?b|(?>aa|a||x)+?c)?(?>[ad]{0,2})*?d)+d", "aaacdbaabdcabdbaaacd aacaabdbdcdcaaaadaabcbaadd" },
+ { MUA, 0 | F_NOMATCH | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d" },
+ { MUA, 0 | F_PROPERTY, "\\X", "\xcc\x8d\xcc\x8d#\xcc\x8d\xcc\x8d" },
+ { MUA, 0 | F_PROPERTY, "\\X+..", "\xcc\x8d#\xcc\x8d#\xcc\x8d\xcc\x8d" },
+ { MUA, 0 | F_PROPERTY, "\\X{2,4}", "abcdef" },
+ { MUA, 0 | F_PROPERTY, "\\X{2,4}?", "abcdef" },
+ { MUA, 0 | F_NOMATCH | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d##" },
+ { MUA, 0 | F_PROPERTY, "\\X{2,4}..", "#\xcc\x8d#\xcc\x8d##" },
+ { MUA, 0, "(c(ab)?+ab)+", "cabcababcab" },
+ { MUA, 0, "(?>(a+)b)+aabab", "aaaabaaabaabab" },
+
+ /* Possessive quantifiers. */
+ { MUA, 0, "(?:a|b)++m", "mababbaaxababbaam" },
+ { MUA, 0, "(?:a|b)*+m", "mababbaaxababbaam" },
+ { MUA, 0, "(?:a|b)*+m", "ababbaaxababbaam" },
+ { MUA, 0, "(a|b)++m", "mababbaaxababbaam" },
+ { MUA, 0, "(a|b)*+m", "mababbaaxababbaam" },
+ { MUA, 0, "(a|b)*+m", "ababbaaxababbaam" },
+ { MUA, 0, "(a|b(*ACCEPT))++m", "maaxab" },
+ { MUA, 0, "(?:b*)++m", "bxbbxbbbxm" },
+ { MUA, 0, "(?:b*)++m", "bxbbxbbbxbbm" },
+ { MUA, 0, "(?:b*)*+m", "bxbbxbbbxm" },
+ { MUA, 0, "(?:b*)*+m", "bxbbxbbbxbbm" },
+ { MUA, 0, "(b*)++m", "bxbbxbbbxm" },
+ { MUA, 0, "(b*)++m", "bxbbxbbbxbbm" },
+ { MUA, 0, "(b*)*+m", "bxbbxbbbxm" },
+ { MUA, 0, "(b*)*+m", "bxbbxbbbxbbm" },
+ { MUA, 0, "(?:a|(b))++m", "mababbaaxababbaam" },
+ { MUA, 0, "(?:(a)|b)*+m", "mababbaaxababbaam" },
+ { MUA, 0, "(?:(a)|(b))*+m", "ababbaaxababbaam" },
+ { MUA, 0, "(a|(b))++m", "mababbaaxababbaam" },
+ { MUA, 0, "((a)|b)*+m", "mababbaaxababbaam" },
+ { MUA, 0, "((a)|(b))*+m", "ababbaaxababbaam" },
+ { MUA, 0, "(a|(b)(*ACCEPT))++m", "maaxab" },
+ { MUA, 0, "(?:(b*))++m", "bxbbxbbbxm" },
+ { MUA, 0, "(?:(b*))++m", "bxbbxbbbxbbm" },
+ { MUA, 0, "(?:(b*))*+m", "bxbbxbbbxm" },
+ { MUA, 0, "(?:(b*))*+m", "bxbbxbbbxbbm" },
+ { MUA, 0, "((b*))++m", "bxbbxbbbxm" },
+ { MUA, 0, "((b*))++m", "bxbbxbbbxbbm" },
+ { MUA, 0, "((b*))*+m", "bxbbxbbbxm" },
+ { MUA, 0, "((b*))*+m", "bxbbxbbbxbbm" },
+ { MUA, 0 | F_NOMATCH, "(?>(b{2,4}))(?:(?:(aa|c))++m|(?:(aa|c))+n)", "bbaacaaccaaaacxbbbmbn" },
+ { MUA, 0, "((?:b)++a)+(cd)*+m", "bbababbacdcdnbbababbacdcdm" },
+ { MUA, 0, "((?:(b))++a)+((c)d)*+m", "bbababbacdcdnbbababbacdcdm" },
+ { MUA, 0, "(?:(?:(?:ab)*+k)++(?:n(?:cd)++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" },
+ { MUA, 0, "(?:((ab)*+(k))++(n(?:c(d))++)*+)*+m", "ababkkXababkkabkncXababkkabkncdcdncdXababkkabkncdcdncdkkabkncdXababkkabkncdcdncdkkabkncdm" },
+
+ /* Back references. */
+ { MUA, 0, "(aa|bb)(\\1*)(ll|)(\\3*)bbbbbbc", "aaaaaabbbbbbbbc" },
+ { CMUA, 0, "(aa|bb)(\\1+)(ll|)(\\3+)bbbbbbc", "bBbbBbCbBbbbBbbcbbBbbbBBbbC" },
+ { CMA, 0, "(a{2,4})\\1", "AaAaaAaA" },
+ { MUA, 0, "(aa|bb)(\\1?)aa(\\1?)(ll|)(\\4+)bbc", "aaaaaaaabbaabbbbaabbbbc" },
+ { MUA, 0, "(aa|bb)(\\1{0,5})(ll|)(\\3{0,5})cc", "bbxxbbbbxxaaaaaaaaaaaaaaaacc" },
+ { MUA, 0, "(aa|bb)(\\1{3,5})(ll|)(\\3{3,5})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" },
+ { MUA, 0, "(aa|bb)(\\1{3,})(ll|)(\\3{3,})cc", "bbbbbbbbbbbbaaaaaaccbbbbbbbbbbbbbbcc" },
+ { MUA, 0, "(\\w+)b(\\1+)c", "GabGaGaDbGaDGaDc" },
+ { MUA, 0, "(?:(aa)|b)\\1?b", "bb" },
+ { CMUA, 0, "(aa|bb)(\\1*?)aa(\\1+?)", "bBBbaaAAaaAAaa" },
+ { MUA, 0, "(aa|bb)(\\1*?)(dd|)cc(\\3+?)", "aaaaaccdd" },
+ { CMUA, 0, "(?:(aa|bb)(\\1?\?)cc){2}(\\1?\?)", "aAaABBbbAAaAcCaAcCaA" },
+ { MUA, 0, "(?:(aa|bb)(\\1{3,5}?)){2}(dd|)(\\3{3,5}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" },
+ { CMA, 0, "(?:(aa|bb)(\\1{3,}?)){2}(dd|)(\\3{3,}?)", "aaaaaabbbbbbbbbbaaaaaaaaaaaaaa" },
+ { MUA, 0, "(?:(aa|bb)(\\1{0,3}?)){2}(dd|)(\\3{0,3}?)b(\\1{0,3}?)(\\1{0,3})", "aaaaaaaaaaaaaaabaaaaa" },
+ { MUA, 0, "(a(?:\\1|)a){3}b", "aaaaaaaaaaab" },
+ { MA, 0, "(a?)b(\\1\\1*\\1+\\1?\\1*?\\1+?\\1??\\1*+\\1++\\1?+\\1{4}\\1{3,5}\\1{4,}\\1{0,5}\\1{3,5}?\\1{4,}?\\1{0,5}?\\1{3,5}+\\1{4,}+\\1{0,5}+#){2}d", "bb#b##d" },
+ { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." },
+ { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{0,2}", "wwwww." },
+ { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwww" },
+ { MUAP, 0 | F_PROPERTY, "(\\P{N})\\1{1,2}ww", "wwwww" },
+ { PCRE_UCP, 0 | F_PROPERTY, "(\\P{N})\\1{2,}", ".www." },
+ { CMUAP, 0, "(\xf0\x90\x90\x80)\\1", "\xf0\x90\x90\xa8\xf0\x90\x90\xa8" },
+
+ /* Assertions. */
+ { MUA, 0, "(?=xx|yy|zz)\\w{4}", "abczzdefg" },
+ { MUA, 0, "(?=((\\w+)b){3}|ab)", "dbbbb ab" },
+ { MUA, 0, "(?!ab|bc|cd)[a-z]{2}", "Xabcdef" },
+ { MUA, 0, "(?<=aaa|aa|a)a", "aaa" },
+ { MUA, 2, "(?<=aaa|aa|a)a", "aaa" },
+ { MA, 0, "(?<=aaa|aa|a)a", "aaa" },
+ { MA, 2, "(?<=aaa|aa|a)a", "aaa" },
+ { MUA, 0, "(\\d{2})(?!\\w+c|(((\\w?)m){2}n)+|\\1)", "x5656" },
+ { MUA, 0, "((?=((\\d{2,6}\\w){2,}))\\w{5,20}K){2,}", "567v09708K12l00M00 567v09708K12l00M00K45K" },
+ { MUA, 0, "(?=(?:(?=\\S+a)\\w*(b)){3})\\w+\\d", "bba bbab nbbkba nbbkba0kl" },
+ { MUA, 0, "(?>a(?>(b+))a(?=(..)))*?k", "acabbcabbaabacabaabbakk" },
+ { MUA, 0, "((?(?=(a))a)+k)", "bbak" },
+ { MUA, 0, "((?(?=a)a)+k)", "bbak" },
+ { MUA, 0 | F_NOMATCH, "(?=(?>(a))m)amk", "a k" },
+ { MUA, 0 | F_NOMATCH, "(?!(?>(a))m)amk", "a k" },
+ { MUA, 0 | F_NOMATCH, "(?>(?=(a))am)amk", "a k" },
+ { MUA, 0, "(?=(?>a|(?=(?>(b+))a|c)[a-c]+)*?m)[a-cm]+k", "aaam bbam baaambaam abbabba baaambaamk" },
+ { MUA, 0, "(?> ?\?\\b(?(?=\\w{1,4}(a))m)\\w{0,8}bc){2,}?", "bca ssbc mabd ssbc mabc" },
+ { MUA, 0, "(?:(?=ab)?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" },
+ { MUA, 0, "(?:(?=a(b))?[^n][^n])+m", "ababcdabcdcdabnababcdabcdcdabm" },
+ { MUA, 0, "(?:(?=.(.))??\\1.)+m", "aabbbcbacccanaabbbcbacccam" },
+ { MUA, 0, "(?:(?=.)??[a-c])+m", "abacdcbacacdcaccam" },
+ { MUA, 0, "((?!a)?(?!([^a]))?)+$", "acbab" },
+ { MUA, 0, "((?!a)?\?(?!([^a]))?\?)+$", "acbab" },
+
+ /* Not empty, ACCEPT, FAIL */
+ { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "a*", "bcx" },
+ { MUA | PCRE_NOTEMPTY, 0, "a*", "bcaad" },
+ { MUA | PCRE_NOTEMPTY, 0, "a*?", "bcaad" },
+ { MUA | PCRE_NOTEMPTY_ATSTART, 0, "a*", "bcaad" },
+ { MUA, 0, "a(*ACCEPT)b", "ab" },
+ { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "a*(*ACCEPT)b", "bcx" },
+ { MUA | PCRE_NOTEMPTY, 0, "a*(*ACCEPT)b", "bcaad" },
+ { MUA | PCRE_NOTEMPTY, 0, "a*?(*ACCEPT)b", "bcaad" },
+ { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "(?:z|a*(*ACCEPT)b)", "bcx" },
+ { MUA | PCRE_NOTEMPTY, 0, "(?:z|a*(*ACCEPT)b)", "bcaad" },
+ { MUA | PCRE_NOTEMPTY, 0, "(?:z|a*?(*ACCEPT)b)", "bcaad" },
+ { MUA | PCRE_NOTEMPTY_ATSTART, 0, "a*(*ACCEPT)b", "bcx" },
+ { MUA | PCRE_NOTEMPTY_ATSTART, 0 | F_NOMATCH, "a*(*ACCEPT)b", "" },
+ { MUA, 0, "((a(*ACCEPT)b))", "ab" },
+ { MUA, 0, "(a(*FAIL)a|a)", "aaa" },
+ { MUA, 0, "(?=ab(*ACCEPT)b)a", "ab" },
+ { MUA, 0, "(?=(?:x|ab(*ACCEPT)b))", "ab" },
+ { MUA, 0, "(?=(a(b(*ACCEPT)b)))a", "ab" },
+ { MUA | PCRE_NOTEMPTY, 0, "(?=a*(*ACCEPT))c", "c" },
+
+ /* Conditional blocks. */
+ { MUA, 0, "(?(?=(a))a|b)+k", "ababbalbbadabak" },
+ { MUA, 0, "(?(?!(b))a|b)+k", "ababbalbbadabak" },
+ { MUA, 0, "(?(?=a)a|b)+k", "ababbalbbadabak" },
+ { MUA, 0, "(?(?!b)a|b)+k", "ababbalbbadabak" },
+ { MUA, 0, "(?(?=(a))a*|b*)+k", "ababbalbbadabak" },
+ { MUA, 0, "(?(?!(b))a*|b*)+k", "ababbalbbadabak" },
+ { MUA, 0, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" },
+ { MUA, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+aaaak", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb aaaaaaak" },
+ { MUA, 0 | F_DIFF, "(?(?!(b))(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" },
+ { MUA, 0, "(?(?!b)(?:aaaaaa|a)|(?:bbbbbb|b))+bbbbk", "aaaaaaaaaaaaaa bbbbbbbbbbbbbbb bbbbbbbk" },
+ { MUA, 0, "(?(?=a)a*|b*)+k", "ababbalbbadabak" },
+ { MUA, 0, "(?(?!b)a*|b*)+k", "ababbalbbadabak" },
+ { MUA, 0, "(?(?=a)ab)", "a" },
+ { MUA, 0, "(?(?a)?(?Pb)?(?(Name)c|d)*l", "bc ddd abccabccl" },
+ { MUA, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+?dd", "bcabcacdb bdddd" },
+ { MUA, 0, "(?Pa)?(?Pb)?(?(Name)c|d)+l", "ababccddabdbccd abcccl" },
+
+ /* Set start of match. */
+ { MUA, 0, "(?:\\Ka)*aaaab", "aaaaaaaa aaaaaaabb" },
+ { MUA, 0, "(?>\\Ka\\Ka)*aaaab", "aaaaaaaa aaaaaaaaaabb" },
+ { MUA, 0, "a+\\K(?<=\\Gaa)a", "aaaaaa" },
+ { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "a\\K(*ACCEPT)b", "aa" },
+ { MUA | PCRE_NOTEMPTY_ATSTART, 0, "a\\K(*ACCEPT)b", "aa" },
+
+ /* First line. */
+ { MUA | PCRE_FIRSTLINE, 0 | F_PROPERTY, "\\p{Any}a", "bb\naaa" },
+ { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}a", "bb\r\naaa" },
+ { MUA | PCRE_FIRSTLINE, 0, "(?<=a)", "a" },
+ { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "[^a][^b]", "ab" },
+ { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "a", "\na" },
+ { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "[abc]", "\na" },
+ { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "^a", "\na" },
+ { MUA | PCRE_FIRSTLINE, 0 | F_NOMATCH, "^(?<=\n)", "\na" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY | PCRE_FIRSTLINE, 0 | F_NOMATCH, "#", "\xc2\x85#" },
+ { PCRE_MULTILINE | PCRE_NEWLINE_ANY | PCRE_FIRSTLINE, 0 | F_NOMATCH, "#", "\x85#" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_ANY | PCRE_FIRSTLINE, 0 | F_NOMATCH, "^#", "\xe2\x80\xa8#" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0 | F_PROPERTY, "\\p{Any}", "\r\na" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0, ".", "\r" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0, "a", "\ra" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0 | F_NOMATCH, "ba", "bbb\r\nba" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 0 | F_NOMATCH | F_PROPERTY, "\\p{Any}{4}|a", "\r\na" },
+ { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 1, ".", "\r\n" },
+
+ /* Recurse. */
+ { MUA, 0, "(a)(?1)", "aa" },
+ { MUA, 0, "((a))(?1)", "aa" },
+ { MUA, 0, "(b|a)(?1)", "aa" },
+ { MUA, 0, "(b|(a))(?1)", "aa" },
+ { MUA, 0 | F_NOMATCH, "((a)(b)(?:a*))(?1)", "aba" },
+ { MUA, 0, "((a)(b)(?:a*))(?1)", "abab" },
+ { MUA, 0, "((a+)c(?2))b(?1)", "aacaabaca" },
+ { MUA, 0, "((?2)b|(a)){2}(?1)", "aabab" },
+ { MUA, 0, "(?1)(a)*+(?2)(b(?1))", "aababa" },
+ { MUA, 0, "(?1)(((a(*ACCEPT)))b)", "axaa" },
+ { MUA, 0, "(?1)(?(DEFINE) (((ac(*ACCEPT)))b) )", "akaac" },
+ { MUA, 0, "(a+)b(?1)b\\1", "abaaabaaaaa" },
+ { MUA, 0 | F_NOMATCH, "(?(DEFINE)(aa|a))(?1)ab", "aab" },
+ { MUA, 0, "(?(DEFINE)(a\\Kb))(?1)+ababc", "abababxabababc" },
+ { MUA, 0, "(a\\Kb)(?1)+ababc", "abababxababababc" },
+ { MUA, 0 | F_NOMATCH, "(a\\Kb)(?1)+ababc", "abababxababababxc" },
+ { MUA, 0, "b|<(?R)*>", "<" },
+ { MUA, 0, "(a\\K){0}(?:(?1)b|ac)", "ac" },
+ { MUA, 0, "(?(DEFINE)(a(?2)|b)(b(?1)|(a)))(?:(?1)|(?2))m", "ababababnababababaam" },
+ { MUA, 0, "(a)((?(R)a|b))(?2)", "aabbabaa" },
+ { MUA, 0, "(a)((?(R2)a|b))(?2)", "aabbabaa" },
+ { MUA, 0, "(a)((?(R1)a|b))(?2)", "ababba" },
+ { MUA, 0, "(?(R0)aa|bb(?R))", "abba aabb bbaa" },
+ { MUA, 0, "((?(R)(?:aaaa|a)|(?:(aaaa)|(a)))+)(?1)$", "aaaaaaaaaa aaaa" },
+ { MUA, 0, "(?Pa(?(R&Name)a|b))(?1)", "aab abb abaa" },
+
+ /* 16 bit specific tests. */
+ { CMA, 0 | F_FORCECONV, "\xc3\xa1", "\xc3\x81\xc3\xa1" },
+ { CMA, 0 | F_FORCECONV, "\xe1\xbd\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" },
+ { CMA, 0 | F_FORCECONV, "[\xc3\xa1]", "\xc3\x81\xc3\xa1" },
+ { CMA, 0 | F_FORCECONV, "[\xe1\xbd\xb8]", "\xe1\xbf\xb8\xe1\xbd\xb8" },
+ { CMA, 0 | F_FORCECONV, "[a-\xed\xb0\x80]", "A" },
+ { CMA, 0 | F_NO8 | F_FORCECONV, "[a-\\x{dc00}]", "B" },
+ { CMA, 0 | F_NO8 | F_NOMATCH | F_FORCECONV, "[b-\\x{dc00}]", "a" },
+ { CMA, 0 | F_NO8 | F_FORCECONV, "\xed\xa0\x80\\x{d800}\xed\xb0\x80\\x{dc00}", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80" },
+ { CMA, 0 | F_NO8 | F_FORCECONV, "[\xed\xa0\x80\\x{d800}]{1,2}?[\xed\xb0\x80\\x{dc00}]{1,2}?#", "\xed\xa0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80#" },
+ { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80\xed\xb0\x80#]{0,3}(?<=\xed\xb0\x80.)", "\xed\xa0\x80#\xed\xa0\x80##\xed\xb0\x80\xed\xa0\x80" },
+ { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\x9f\xbf\xed\xa0\x83" },
+ { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80-\xed\xb3\xbf]", "\xed\xb4\x80\xed\xb3\xb0" },
+ { CMA, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\x9f\xbf\xed\xa0\x83" },
+ { CMA, 0 | F_NO8 | F_FORCECONV, "[\\x{d800}-\\x{dcff}]", "\xed\xb4\x80\xed\xb3\xb0" },
+ { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80-\xef\xbf\xbf]+[\x1-\xed\xb0\x80]+#", "\xed\xa0\x85\xc3\x81\xed\xa0\x85\xef\xbf\xb0\xc2\x85\xed\xa9\x89#" },
+ { CMA, 0 | F_FORCECONV, "[\xed\xa0\x80][\xed\xb0\x80]{2,}", "\xed\xa0\x80\xed\xb0\x80\xed\xa0\x80\xed\xb0\x80\xed\xb0\x80\xed\xb0\x80" },
+ { MA, 0 | F_FORCECONV, "[^\xed\xb0\x80]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" },
+ { MA, 0 | F_NO8 | F_FORCECONV, "[^\\x{dc00}]{3,}?", "##\xed\xb0\x80#\xed\xb0\x80#\xc3\x89#\xed\xb0\x80" },
+ { CMA, 0 | F_FORCECONV, ".\\B.", "\xed\xa0\x80\xed\xb0\x80" },
+ { CMA, 0 | F_FORCECONV, "\\D+(?:\\d+|.)\\S+(?:\\s+|.)\\W+(?:\\w+|.)\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80" },
+ { CMA, 0 | F_FORCECONV, "\\d*\\s*\\w*\xed\xa0\x80\xed\xa0\x80", "\xed\xa0\x80\xed\xa0\x80" },
+ { CMA, 0 | F_FORCECONV | F_NOMATCH, "\\d*?\\D*?\\s*?\\S*?\\w*?\\W*?##", "\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80\xed\xa0\x80#" },
+ { CMA | PCRE_EXTENDED, 0 | F_FORCECONV, "\xed\xa0\x80 \xed\xb0\x80 !", "\xed\xa0\x80\xed\xb0\x80!" },
+ { CMA, 0 | F_FORCECONV, "\xed\xa0\x80+#[^#]+\xed\xa0\x80", "\xed\xa0\x80#a\xed\xa0\x80" },
+ { CMA, 0 | F_FORCECONV, "(\xed\xa0\x80+)#\\1", "\xed\xa0\x80\xed\xa0\x80#\xed\xa0\x80\xed\xa0\x80" },
+ { PCRE_MULTILINE | PCRE_NEWLINE_ANY, 0 | F_NO8 | F_FORCECONV, "^-", "a--\xe2\x80\xa8--" },
+ { PCRE_BSR_UNICODE, 0 | F_NO8 | F_FORCECONV, "\\R", "ab\xe2\x80\xa8" },
+ { 0, 0 | F_NO8 | F_FORCECONV, "\\v", "ab\xe2\x80\xa9" },
+ { 0, 0 | F_NO8 | F_FORCECONV, "\\h", "ab\xe1\xa0\x8e" },
+ { 0, 0 | F_NO8 | F_FORCECONV, "\\v+?\\V+?#", "\xe2\x80\xa9\xe2\x80\xa9\xef\xbf\xbf\xef\xbf\xbf#" },
+ { 0, 0 | F_NO8 | F_FORCECONV, "\\h+?\\H+?#", "\xe1\xa0\x8e\xe1\xa0\x8e\xef\xbf\xbf\xef\xbf\xbf#" },
+
+ /* Partial matching. */
+ { MUA | PCRE_PARTIAL_SOFT, 0, "ab", "a" },
+ { MUA | PCRE_PARTIAL_SOFT, 0, "ab|a", "a" },
+ { MUA | PCRE_PARTIAL_HARD, 0, "ab|a", "a" },
+ { MUA | PCRE_PARTIAL_SOFT, 0, "\\b#", "a" },
+ { MUA | PCRE_PARTIAL_SOFT, 0, "(?<=a)b", "a" },
+ { MUA | PCRE_PARTIAL_SOFT, 0, "abc|(?<=xxa)bc", "xxab" },
+ { MUA | PCRE_PARTIAL_SOFT, 0, "a\\B", "a" },
+ { MUA | PCRE_PARTIAL_HARD, 0, "a\\b", "a" },
+
+ /* (*MARK) verb. */
+ { MUA, 0, "a(*MARK:aa)a", "ababaa" },
+ { MUA, 0 | F_NOMATCH, "a(*:aa)a", "abab" },
+ { MUA, 0, "a(*:aa)(b(*:bb)b|bc)", "abc" },
+ { MUA, 0 | F_NOMATCH, "a(*:1)x|b(*:2)y", "abc" },
+ { MUA, 0, "(?>a(*:aa))b|ac", "ac" },
+ { MUA, 0, "(?(DEFINE)(a(*:aa)))(?1)", "a" },
+ { MUA, 0 | F_NOMATCH, "(?(DEFINE)((a)(*:aa)))(?1)b", "aa" },
+ { MUA, 0, "(?(DEFINE)(a(*:aa)))a(?1)b|aac", "aac" },
+ { MUA, 0, "(a(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" },
+ { MUA, 0, "(a(*:aa)){0}(?:b(?1)b)+", "babba" },
+ { MUA, 0 | F_NOMATCH, "(a(*:aa)){0}(?:b(?1)b)+", "ba" },
+ { MUA, 0, "(a\\K(*:aa)){0}(?:b(?1)b|c)+c", "babbab cc" },
+ { MUA, 0, "(a\\K(*:aa)){0}(?:b(?1)b)+", "babba" },
+ { MUA, 0 | F_NOMATCH, "(a\\K(*:aa)){0}(?:b(?1)b)+", "ba" },
+
+ /* (*COMMIT) verb. */
+ { MUA, 0 | F_NOMATCH, "a(*COMMIT)b", "ac" },
+ { MUA, 0, "aa(*COMMIT)b", "xaxaab" },
+ { MUA, 0 | F_NOMATCH, "a(*COMMIT)(*:msg)b|ac", "ac" },
+ { MUA, 0, "(?=a(*COMMIT)b|ac)ac|(*:m)(a)c", "ac" },
+ { MUA, 0, "(?!a(*COMMIT)(*:msg)b)a(c)|cd", "acd" },
+
+ /* Deep recursion. */
+ { MUA, 0, "((((?:(?:(?:\\w)+)?)*|(?>\\w)+?)+|(?>\\w)?\?)*)?\\s", "aaaaa+ " },
+ { MUA, 0, "(?:((?:(?:(?:\\w*?)+)??|(?>\\w)?|\\w*+)*)+)+?\\s", "aa+ " },
+ { MUA, 0, "((a?)+)+b", "aaaaaaaaaaaa b" },
+
+ /* Deep recursion: Stack limit reached. */
+ { MA, 0 | F_NOMATCH, "a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaa" },
+ { MA, 0 | F_NOMATCH, "(?:a+)+b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },
+ { MA, 0 | F_NOMATCH, "(?:a+?)+?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },
+ { MA, 0 | F_NOMATCH, "(?:a*)*b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },
+ { MA, 0 | F_NOMATCH, "(?:a*?)*?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" },
+
+ { 0, 0, NULL, NULL }
+};
+
+static const unsigned char *tables(int mode)
+{
+ /* The purpose of this function to allow valgrind
+ for reporting invalid reads and writes. */
+ static unsigned char *tables_copy;
+ const char *errorptr;
+ int erroroffset;
+ unsigned char *default_tables;
+#ifdef SUPPORT_PCRE8
+ pcre *regex;
+ char null_str[1] = { 0 };
+#else
+ pcre16 *regex;
+ PCRE_UCHAR16 null_str[1] = { 0 };
+#endif
+
+ if (mode) {
+ if (tables_copy)
+ free(tables_copy);
+ tables_copy = NULL;
+ return NULL;
+ }
+
+ if (tables_copy)
+ return tables_copy;
+
+ default_tables = NULL;
+#ifdef SUPPORT_PCRE8
+ regex = pcre_compile(null_str, 0, &errorptr, &erroroffset, NULL);
+ if (regex) {
+ pcre_fullinfo(regex, NULL, PCRE_INFO_DEFAULT_TABLES, &default_tables);
+ pcre_free(regex);
+ }
+#else
+ regex = pcre16_compile(null_str, 0, &errorptr, &erroroffset, NULL);
+ if (regex) {
+ pcre16_fullinfo(regex, NULL, PCRE_INFO_DEFAULT_TABLES, &default_tables);
+ pcre16_free(regex);
+ }
+#endif
+ /* Shouldn't ever happen. */
+ if (!default_tables)
+ return NULL;
+
+ /* Unfortunately this value cannot get from pcre_fullinfo.
+ Since this is a test program, this is acceptable at the moment. */
+ tables_copy = (unsigned char *)malloc(1088);
+ if (!tables_copy)
+ return NULL;
+
+ memcpy(tables_copy, default_tables, 1088);
+ return tables_copy;
+}
+
+#ifdef SUPPORT_PCRE8
+static pcre_jit_stack* callback8(void *arg)
+{
+ return (pcre_jit_stack *)arg;
+}
+#endif
+
+#ifdef SUPPORT_PCRE16
+static pcre16_jit_stack* callback16(void *arg)
+{
+ return (pcre16_jit_stack *)arg;
+}
+#endif
+
+#ifdef SUPPORT_PCRE8
+static void setstack8(pcre_extra *extra)
+{
+ static pcre_jit_stack *stack;
+
+ if (!extra) {
+ if (stack)
+ pcre_jit_stack_free(stack);
+ stack = NULL;
+ return;
+ }
+
+ if (!stack)
+ stack = pcre_jit_stack_alloc(1, 1024 * 1024);
+ /* Extra can be NULL. */
+ pcre_assign_jit_stack(extra, callback8, stack);
+}
+#endif /* SUPPORT_PCRE8 */
+
+#ifdef SUPPORT_PCRE16
+static void setstack16(pcre16_extra *extra)
+{
+ static pcre16_jit_stack *stack;
+
+ if (!extra) {
+ if (stack)
+ pcre16_jit_stack_free(stack);
+ stack = NULL;
+ return;
+ }
+
+ if (!stack)
+ stack = pcre16_jit_stack_alloc(1, 1024 * 1024);
+ /* Extra can be NULL. */
+ pcre16_assign_jit_stack(extra, callback16, stack);
+}
+#endif /* SUPPORT_PCRE8 */
+
+#ifdef SUPPORT_PCRE16
+
+static int convert_utf8_to_utf16(const char *input, PCRE_UCHAR16 *output, int *offsetmap, int max_length)
+{
+ unsigned char *iptr = (unsigned char*)input;
+ unsigned short *optr = (unsigned short *)output;
+ unsigned int c;
+
+ if (max_length == 0)
+ return 0;
+
+ while (*iptr && max_length > 1) {
+ c = 0;
+ if (offsetmap)
+ *offsetmap++ = (int)(iptr - (unsigned char*)input);
+
+ if (!(*iptr & 0x80))
+ c = *iptr++;
+ else if (!(*iptr & 0x20)) {
+ c = ((iptr[0] & 0x1f) << 6) | (iptr[1] & 0x3f);
+ iptr += 2;
+ } else if (!(*iptr & 0x10)) {
+ c = ((iptr[0] & 0x0f) << 12) | ((iptr[1] & 0x3f) << 6) | (iptr[2] & 0x3f);
+ iptr += 3;
+ } else if (!(*iptr & 0x08)) {
+ c = ((iptr[0] & 0x07) << 18) | ((iptr[1] & 0x3f) << 12) | ((iptr[2] & 0x3f) << 6) | (iptr[3] & 0x3f);
+ iptr += 4;
+ }
+
+ if (c < 65536) {
+ *optr++ = c;
+ max_length--;
+ } else if (max_length <= 2) {
+ *optr = '\0';
+ return (int)(optr - (unsigned short *)output);
+ } else {
+ c -= 0x10000;
+ *optr++ = 0xd800 | ((c >> 10) & 0x3ff);
+ *optr++ = 0xdc00 | (c & 0x3ff);
+ max_length -= 2;
+ if (offsetmap)
+ offsetmap++;
+ }
+ }
+ if (offsetmap)
+ *offsetmap = (int)(iptr - (unsigned char*)input);
+ *optr = '\0';
+ return (int)(optr - (unsigned short *)output);
+}
+
+static int copy_char8_to_char16(const char *input, PCRE_UCHAR16 *output, int max_length)
+{
+ unsigned char *iptr = (unsigned char*)input;
+ unsigned short *optr = (unsigned short *)output;
+
+ if (max_length == 0)
+ return 0;
+
+ while (*iptr && max_length > 1) {
+ *optr++ = *iptr++;
+ max_length--;
+ }
+ *optr = '\0';
+ return (int)(optr - (unsigned short *)output);
+}
+
+#define REGTEST_MAX_LENGTH 4096
+static PCRE_UCHAR16 regtest_buf[REGTEST_MAX_LENGTH];
+static int regtest_offsetmap[REGTEST_MAX_LENGTH];
+
+#endif /* SUPPORT_PCRE16 */
+
+static int check_ascii(const char *input)
+{
+ const unsigned char *ptr = (unsigned char *)input;
+ while (*ptr) {
+ if (*ptr > 127)
+ return 0;
+ ptr++;
+ }
+ return 1;
+}
+
+static int regression_tests(void)
+{
+ struct regression_test_case *current = regression_test_cases;
+ const char *error;
+ char *cpu_info;
+ int i, err_offs;
+ int is_successful, is_ascii_pattern, is_ascii_input;
+ int total = 0;
+ int successful = 0;
+ int successful_row = 0;
+ int counter = 0;
+ int study_mode;
+#ifdef SUPPORT_PCRE8
+ pcre *re8;
+ pcre_extra *extra8;
+ pcre_extra dummy_extra8;
+ int ovector8_1[32];
+ int ovector8_2[32];
+ int return_value8_1, return_value8_2;
+ unsigned char *mark8_1, *mark8_2;
+ int utf8 = 0, ucp8 = 0;
+ int disabled_flags8 = 0;
+#endif
+#ifdef SUPPORT_PCRE16
+ pcre16 *re16;
+ pcre16_extra *extra16;
+ pcre16_extra dummy_extra16;
+ int ovector16_1[32];
+ int ovector16_2[32];
+ int return_value16_1, return_value16_2;
+ PCRE_UCHAR16 *mark16_1, *mark16_2;
+ int utf16 = 0, ucp16 = 0;
+ int disabled_flags16 = 0;
+ int length16;
+#endif
+
+ /* This test compares the behaviour of interpreter and JIT. Although disabling
+ utf or ucp may make tests fail, if the pcre_exec result is the SAME, it is
+ still considered successful from pcre_jit_test point of view. */
+
+#ifdef SUPPORT_PCRE8
+ pcre_config(PCRE_CONFIG_JITTARGET, &cpu_info);
+#else
+ pcre16_config(PCRE_CONFIG_JITTARGET, &cpu_info);
+#endif
+
+ printf("Running JIT regression tests\n");
+ printf(" target CPU of SLJIT compiler: %s\n", cpu_info);
+
+#ifdef SUPPORT_PCRE8
+ pcre_config(PCRE_CONFIG_UTF8, &utf8);
+ pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp8);
+ if (!utf8)
+ disabled_flags8 |= PCRE_UTF8;
+ if (!ucp8)
+ disabled_flags8 |= PCRE_UCP;
+ printf(" in 8 bit mode with utf8 %s and ucp %s:\n", utf8 ? "enabled" : "disabled", ucp8 ? "enabled" : "disabled");
+#endif
+#ifdef SUPPORT_PCRE16
+ pcre16_config(PCRE_CONFIG_UTF16, &utf16);
+ pcre16_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp16);
+ if (!utf16)
+ disabled_flags16 |= PCRE_UTF8;
+ if (!ucp16)
+ disabled_flags16 |= PCRE_UCP;
+ printf(" in 16 bit mode with utf16 %s and ucp %s:\n", utf16 ? "enabled" : "disabled", ucp16 ? "enabled" : "disabled");
+#endif
+
+ while (current->pattern) {
+ /* printf("\nPattern: %s :\n", current->pattern); */
+ total++;
+ if (current->start_offset & F_PROPERTY) {
+ is_ascii_pattern = 0;
+ is_ascii_input = 0;
+ } else {
+ is_ascii_pattern = check_ascii(current->pattern);
+ is_ascii_input = check_ascii(current->input);
+ }
+
+ if (current->flags & PCRE_PARTIAL_SOFT)
+ study_mode = PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE;
+ else if (current->flags & PCRE_PARTIAL_HARD)
+ study_mode = PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE;
+ else
+ study_mode = PCRE_STUDY_JIT_COMPILE;
+ error = NULL;
+#ifdef SUPPORT_PCRE8
+ re8 = NULL;
+ if (!(current->start_offset & F_NO8))
+ re8 = pcre_compile(current->pattern,
+ current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | disabled_flags8),
+ &error, &err_offs, tables(0));
+
+ extra8 = NULL;
+ if (re8) {
+ error = NULL;
+ extra8 = pcre_study(re8, study_mode, &error);
+ if (!extra8) {
+ printf("\n8 bit: Cannot study pattern: %s\n", current->pattern);
+ pcre_free(re8);
+ re8 = NULL;
+ }
+ if (!(extra8->flags & PCRE_EXTRA_EXECUTABLE_JIT)) {
+ printf("\n8 bit: JIT compiler does not support: %s\n", current->pattern);
+ pcre_free_study(extra8);
+ pcre_free(re8);
+ re8 = NULL;
+ }
+ extra8->flags |= PCRE_EXTRA_MARK;
+ } else if (((utf8 && ucp8) || is_ascii_pattern) && !(current->start_offset & F_NO8))
+ printf("\n8 bit: Cannot compile pattern: %s\n", current->pattern);
+#endif
+#ifdef SUPPORT_PCRE16
+ if ((current->flags & PCRE_UTF8) || (current->start_offset & F_FORCECONV))
+ convert_utf8_to_utf16(current->pattern, regtest_buf, NULL, REGTEST_MAX_LENGTH);
+ else
+ copy_char8_to_char16(current->pattern, regtest_buf, REGTEST_MAX_LENGTH);
+
+ re16 = NULL;
+ if (!(current->start_offset & F_NO16))
+ re16 = pcre16_compile(regtest_buf,
+ current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD | disabled_flags16),
+ &error, &err_offs, tables(0));
+
+ extra16 = NULL;
+ if (re16) {
+ error = NULL;
+ extra16 = pcre16_study(re16, study_mode, &error);
+ if (!extra16) {
+ printf("\n16 bit: Cannot study pattern: %s\n", current->pattern);
+ pcre16_free(re16);
+ re16 = NULL;
+ }
+ if (!(extra16->flags & PCRE_EXTRA_EXECUTABLE_JIT)) {
+ printf("\n16 bit: JIT compiler does not support: %s\n", current->pattern);
+ pcre16_free_study(extra16);
+ pcre16_free(re16);
+ re16 = NULL;
+ }
+ extra16->flags |= PCRE_EXTRA_MARK;
+ } else if (((utf16 && ucp16) || is_ascii_pattern) && !(current->start_offset & F_NO16))
+ printf("\n16 bit: Cannot compile pattern: %s\n", current->pattern);
+#endif
+
+ counter++;
+ if ((counter & 0x3) != 0) {
+#ifdef SUPPORT_PCRE8
+ setstack8(NULL);
+#endif
+#ifdef SUPPORT_PCRE16
+ setstack16(NULL);
+#endif
+ }
+
+#ifdef SUPPORT_PCRE8
+ return_value8_1 = -1000;
+ return_value8_2 = -1000;
+ for (i = 0; i < 32; ++i)
+ ovector8_1[i] = -2;
+ for (i = 0; i < 32; ++i)
+ ovector8_2[i] = -2;
+ if (re8) {
+ mark8_1 = NULL;
+ mark8_2 = NULL;
+ setstack8(extra8);
+ extra8->mark = &mark8_1;
+ return_value8_1 = pcre_exec(re8, extra8, current->input, strlen(current->input), current->start_offset & OFFSET_MASK,
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector8_1, 32);
+ memset(&dummy_extra8, 0, sizeof(pcre_extra));
+ dummy_extra8.flags = PCRE_EXTRA_MARK;
+ dummy_extra8.mark = &mark8_2;
+ return_value8_2 = pcre_exec(re8, &dummy_extra8, current->input, strlen(current->input), current->start_offset & OFFSET_MASK,
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector8_2, 32);
+ }
+#endif
+
+#ifdef SUPPORT_PCRE16
+ return_value16_1 = -1000;
+ return_value16_2 = -1000;
+ for (i = 0; i < 32; ++i)
+ ovector16_1[i] = -2;
+ for (i = 0; i < 32; ++i)
+ ovector16_2[i] = -2;
+ if (re16) {
+ mark16_1 = NULL;
+ mark16_2 = NULL;
+ setstack16(extra16);
+ if ((current->flags & PCRE_UTF8) || (current->start_offset & F_FORCECONV))
+ length16 = convert_utf8_to_utf16(current->input, regtest_buf, regtest_offsetmap, REGTEST_MAX_LENGTH);
+ else
+ length16 = copy_char8_to_char16(current->input, regtest_buf, REGTEST_MAX_LENGTH);
+ extra16->mark = &mark16_1;
+ return_value16_1 = pcre16_exec(re16, extra16, regtest_buf, length16, current->start_offset & OFFSET_MASK,
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector16_1, 32);
+ memset(&dummy_extra16, 0, sizeof(pcre16_extra));
+ dummy_extra16.flags = PCRE_EXTRA_MARK;
+ dummy_extra16.mark = &mark16_2;
+ return_value16_2 = pcre16_exec(re16, &dummy_extra16, regtest_buf, length16, current->start_offset & OFFSET_MASK,
+ current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD), ovector16_2, 32);
+ }
+#endif
+
+ /* printf("[%d-%d|%d-%d|%d-%d]%s", return_value8_1, return_value16_1, ovector8_1[0], ovector8_1[1], ovector16_1[0], ovector16_1[1], (current->flags & PCRE_CASELESS) ? "C" : ""); */
+
+ /* If F_DIFF is set, just run the test, but do not compare the results.
+ Segfaults can still be captured. */
+
+ is_successful = 1;
+ if (!(current->start_offset & F_DIFF)) {
+#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
+ if (utf8 == utf16 && !(current->start_offset & F_FORCECONV)) {
+ /* All results must be the same. */
+ if (return_value8_1 != return_value8_2 || return_value8_1 != return_value16_1 || return_value8_1 != return_value16_2) {
+ printf("\n8 and 16 bit: Return value differs(%d:%d:%d:%d): [%d] '%s' @ '%s'\n",
+ return_value8_1, return_value8_2, return_value16_1, return_value16_2,
+ total, current->pattern, current->input);
+ is_successful = 0;
+ } else if (return_value8_1 >= 0 || return_value8_1 == PCRE_ERROR_PARTIAL) {
+ if (return_value8_1 == PCRE_ERROR_PARTIAL) {
+ return_value8_1 = 2;
+ return_value16_1 = 2;
+ } else {
+ return_value8_1 *= 2;
+ return_value16_1 *= 2;
+ }
+
+ /* Transform back the results. */
+ if (current->flags & PCRE_UTF8) {
+ for (i = 0; i < return_value8_1; ++i) {
+ if (ovector16_1[i] >= 0)
+ ovector16_1[i] = regtest_offsetmap[ovector16_1[i]];
+ if (ovector16_2[i] >= 0)
+ ovector16_2[i] = regtest_offsetmap[ovector16_2[i]];
+ }
+ }
+
+ for (i = 0; i < return_value8_1; ++i)
+ if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector16_1[i] || ovector8_1[i] != ovector16_2[i]) {
+ printf("\n8 and 16 bit: Ovector[%d] value differs(%d:%d:%d:%d): [%d] '%s' @ '%s' \n",
+ i, ovector8_1[i], ovector8_2[i], ovector16_1[i], ovector16_2[i],
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+ }
+ } else {
+#endif /* SUPPORT_PCRE8 && SUPPORT_PCRE16 */
+ /* Only the 8 bit and 16 bit results must be equal. */
+#ifdef SUPPORT_PCRE8
+ if (return_value8_1 != return_value8_2) {
+ printf("\n8 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n",
+ return_value8_1, return_value8_2, total, current->pattern, current->input);
+ is_successful = 0;
+ } else if (return_value8_1 >= 0 || return_value8_1 == PCRE_ERROR_PARTIAL) {
+ if (return_value8_1 == PCRE_ERROR_PARTIAL)
+ return_value8_1 = 2;
+ else
+ return_value8_1 *= 2;
+
+ for (i = 0; i < return_value8_1; ++i)
+ if (ovector8_1[i] != ovector8_2[i]) {
+ printf("\n8 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n",
+ i, ovector8_1[i], ovector8_2[i], total, current->pattern, current->input);
+ is_successful = 0;
+ }
+ }
+#endif
+
+#ifdef SUPPORT_PCRE16
+ if (return_value16_1 != return_value16_2) {
+ printf("\n16 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n",
+ return_value16_1, return_value16_2, total, current->pattern, current->input);
+ is_successful = 0;
+ } else if (return_value16_1 >= 0 || return_value16_1 == PCRE_ERROR_PARTIAL) {
+ if (return_value16_1 == PCRE_ERROR_PARTIAL)
+ return_value16_1 = 2;
+ else
+ return_value16_1 *= 2;
+
+ for (i = 0; i < return_value16_1; ++i)
+ if (ovector16_1[i] != ovector16_2[i]) {
+ printf("\n16 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n",
+ i, ovector16_1[i], ovector16_2[i], total, current->pattern, current->input);
+ is_successful = 0;
+ }
+ }
+#endif
+
+#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
+ }
+#endif /* SUPPORT_PCRE8 && SUPPORT_PCRE16 */
+ }
+
+ if (is_successful) {
+#ifdef SUPPORT_PCRE8
+ if (!(current->start_offset & F_NO8) && ((utf8 && ucp8) || is_ascii_input)) {
+ if (return_value8_1 < 0 && !(current->start_offset & F_NOMATCH)) {
+ printf("8 bit: Test should match: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+
+ if (return_value8_1 >= 0 && (current->start_offset & F_NOMATCH)) {
+ printf("8 bit: Test should not match: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+ }
+#endif
+#ifdef SUPPORT_PCRE16
+ if (!(current->start_offset & F_NO16) && ((utf16 && ucp16) || is_ascii_input)) {
+ if (return_value16_1 < 0 && !(current->start_offset & F_NOMATCH)) {
+ printf("16 bit: Test should match: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+
+ if (return_value16_1 >= 0 && (current->start_offset & F_NOMATCH)) {
+ printf("16 bit: Test should not match: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+ }
+#endif
+ }
+
+ if (is_successful) {
+#ifdef SUPPORT_PCRE8
+ if (mark8_1 != mark8_2) {
+ printf("8 bit: Mark value mismatch: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+#endif
+#ifdef SUPPORT_PCRE16
+ if (mark16_1 != mark16_2) {
+ printf("16 bit: Mark value mismatch: [%d] '%s' @ '%s'\n",
+ total, current->pattern, current->input);
+ is_successful = 0;
+ }
+#endif
+ }
+
+#ifdef SUPPORT_PCRE8
+ if (re8) {
+ pcre_free_study(extra8);
+ pcre_free(re8);
+ }
+#endif
+#ifdef SUPPORT_PCRE16
+ if (re16) {
+ pcre16_free_study(extra16);
+ pcre16_free(re16);
+ }
+#endif
+
+ if (is_successful) {
+ successful++;
+ successful_row++;
+ printf(".");
+ if (successful_row >= 60) {
+ successful_row = 0;
+ printf("\n");
+ }
+ } else
+ successful_row = 0;
+
+ fflush(stdout);
+ current++;
+ }
+ tables(1);
+#ifdef SUPPORT_PCRE8
+ setstack8(NULL);
+#endif
+#ifdef SUPPORT_PCRE16
+ setstack16(NULL);
+#endif
+
+ if (total == successful) {
+ printf("\nAll JIT regression tests are successfully passed.\n");
+ return 0;
+ } else {
+ printf("\nSuccessful test ratio: %d%% (%d failed)\n", successful * 100 / total, total - successful);
+ return 1;
+ }
+}
+
+/* End of pcre_jit_test.c */
diff -Nru pcre3-8.12/pcre_maketables.c pcre3-8.31/pcre_maketables.c
--- pcre3-8.12/pcre_maketables.c 2008-01-20 19:59:12.000000000 +0000
+++ pcre3-8.31/pcre_maketables.c 2011-12-28 16:57:58.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -59,21 +59,26 @@
/* This function builds a set of character tables for use by PCRE and returns
a pointer to them. They are build using the ctype functions, and consequently
their contents will depend upon the current locale setting. When compiled as
-part of the library, the store is obtained via pcre_malloc(), but when compiled
-inside dftables, use malloc().
+part of the library, the store is obtained via PUBL(malloc)(), but when
+compiled inside dftables, use malloc().
Arguments: none
Returns: pointer to the contiguous block of data
*/
+#ifdef COMPILE_PCRE8
const unsigned char *
pcre_maketables(void)
+#else
+const unsigned char *
+pcre16_maketables(void)
+#endif
{
unsigned char *yield, *p;
int i;
#ifndef DFTABLES
-yield = (unsigned char*)(pcre_malloc)(tables_length);
+yield = (unsigned char*)(PUBL(malloc))(tables_length);
#else
yield = (unsigned char*)malloc(tables_length);
#endif
diff -Nru pcre3-8.12/pcre_newline.c pcre3-8.31/pcre_newline.c
--- pcre3-8.12/pcre_newline.c 2009-03-28 17:06:38.000000000 +0000
+++ pcre3-8.31/pcre_newline.c 2011-12-28 16:57:58.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2009 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -67,16 +67,25 @@
type the newline type
endptr pointer to the end of the string
lenptr where to return the length
- utf8 TRUE if in utf8 mode
+ utf TRUE if in utf mode
Returns: TRUE or FALSE
*/
BOOL
-_pcre_is_newline(USPTR ptr, int type, USPTR endptr, int *lenptr, BOOL utf8)
+PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr,
+ BOOL utf)
{
int c;
-if (utf8) { GETCHAR(c, ptr); } else c = *ptr;
+(void)utf;
+#ifdef SUPPORT_UTF
+if (utf)
+ {
+ GETCHAR(c, ptr);
+ }
+else
+#endif /* SUPPORT_UTF */
+ c = *ptr;
if (type == NLTYPE_ANYCRLF) switch(c)
{
@@ -95,9 +104,15 @@
case 0x000c: *lenptr = 1; return TRUE; /* FF */
case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
return TRUE; /* CR */
- case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */
+#ifdef COMPILE_PCRE8
+ case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
case 0x2028: /* LS */
case 0x2029: *lenptr = 3; return TRUE; /* PS */
+#else
+ case 0x0085: /* NEL */
+ case 0x2028: /* LS */
+ case 0x2029: *lenptr = 1; return TRUE; /* PS */
+#endif /* COMPILE_PCRE8 */
default: return FALSE;
}
}
@@ -116,26 +131,27 @@
type the newline type
startptr pointer to the start of the string
lenptr where to return the length
- utf8 TRUE if in utf8 mode
+ utf TRUE if in utf mode
Returns: TRUE or FALSE
*/
BOOL
-_pcre_was_newline(USPTR ptr, int type, USPTR startptr, int *lenptr, BOOL utf8)
+PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr,
+ BOOL utf)
{
int c;
+(void)utf;
ptr--;
-#ifdef SUPPORT_UTF8
-if (utf8)
+#ifdef SUPPORT_UTF
+if (utf)
{
BACKCHAR(ptr);
GETCHAR(c, ptr);
}
-else c = *ptr;
-#else /* no UTF-8 support */
-c = *ptr;
-#endif /* SUPPORT_UTF8 */
+else
+#endif /* SUPPORT_UTF */
+ c = *ptr;
if (type == NLTYPE_ANYCRLF) switch(c)
{
@@ -152,9 +168,15 @@
case 0x000b: /* VT */
case 0x000c: /* FF */
case 0x000d: *lenptr = 1; return TRUE; /* CR */
- case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */
+#ifdef COMPILE_PCRE8
+ case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
case 0x2028: /* LS */
case 0x2029: *lenptr = 3; return TRUE; /* PS */
+#else
+ case 0x0085: /* NEL */
+ case 0x2028: /* LS */
+ case 0x2029: *lenptr = 1; return TRUE; /* PS */
+#endif /* COMPILE_PCRE8 */
default: return FALSE;
}
}
diff -Nru pcre3-8.12/pcre_ord2utf8.c pcre3-8.31/pcre_ord2utf8.c
--- pcre3-8.12/pcre_ord2utf8.c 2008-08-25 18:27:26.000000000 +0000
+++ pcre3-8.31/pcre_ord2utf8.c 2012-01-23 17:11:03.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -52,35 +52,45 @@
* Convert character value to UTF-8 *
*************************************************/
-/* This function takes an integer value in the range 0 - 0x7fffffff
-and encodes it as a UTF-8 character in 0 to 6 bytes.
+/* This function takes an integer value in the range 0 - 0x10ffff
+and encodes it as a UTF-8 character in 1 to 6 pcre_uchars.
Arguments:
cvalue the character value
- buffer pointer to buffer for result - at least 6 bytes long
+ buffer pointer to buffer for result - at least 6 pcre_uchars long
Returns: number of characters placed in the buffer
*/
int
-_pcre_ord2utf8(int cvalue, uschar *buffer)
+PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer)
{
-#ifdef SUPPORT_UTF8
+#ifdef SUPPORT_UTF
+
register int i, j;
-for (i = 0; i < _pcre_utf8_table1_size; i++)
- if (cvalue <= _pcre_utf8_table1[i]) break;
+
+/* Checking invalid cvalue character, encoded as invalid UTF-16 character.
+Should never happen in practice. */
+if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000)
+ cvalue = 0xfffe;
+
+for (i = 0; i < PRIV(utf8_table1_size); i++)
+ if ((int)cvalue <= PRIV(utf8_table1)[i]) break;
buffer += i;
for (j = i; j > 0; j--)
{
*buffer-- = 0x80 | (cvalue & 0x3f);
cvalue >>= 6;
}
-*buffer = _pcre_utf8_table2[i] | cvalue;
+*buffer = PRIV(utf8_table2)[i] | cvalue;
return i + 1;
+
#else
+
(void)(cvalue); /* Keep compiler happy; this function won't ever be */
-(void)(buffer); /* called when SUPPORT_UTF8 is not defined. */
+(void)(buffer); /* called when SUPPORT_UTF is not defined. */
return 0;
+
#endif
}
diff -Nru pcre3-8.12/pcre_printint.c pcre3-8.31/pcre_printint.c
--- pcre3-8.12/pcre_printint.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre_printint.c 2012-02-22 13:54:41.000000000 +0000
@@ -0,0 +1,710 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains a PCRE private debugging function for printing out the
+internal form of a compiled regular expression, along with some supporting
+local functions. This source file is used in two places:
+
+(1) It is #included by pcre_compile.c when it is compiled in debugging mode
+(PCRE_DEBUG defined in pcre_internal.h). It is not included in production
+compiles. In this case PCRE_INCLUDED is defined.
+
+(2) It is also compiled separately and linked with pcretest.c, which can be
+asked to print out a compiled regex for debugging purposes. */
+
+#ifndef PCRE_INCLUDED
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* For pcretest program. */
+#define PRIV(name) name
+
+/* We have to include pcre_internal.h because we need the internal info for
+displaying the results of pcre_study() and we also need to know about the
+internal macros, structures, and other internal data values; pcretest has
+"inside information" compared to a program that strictly follows the PCRE API.
+
+Although pcre_internal.h does itself include pcre.h, we explicitly include it
+here before pcre_internal.h so that the PCRE_EXP_xxx macros get set
+appropriately for an application, not for building PCRE. */
+
+#include "pcre.h"
+#include "pcre_internal.h"
+
+/* These are the funtions that are contained within. It doesn't seem worth
+having a separate .h file just for this. */
+
+#endif /* PCRE_INCLUDED */
+
+#ifdef PCRE_INCLUDED
+static /* Keep the following function as private. */
+#endif
+#ifdef COMPILE_PCRE8
+void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths);
+#else
+void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths);
+#endif
+
+/* Macro that decides whether a character should be output as a literal or in
+hexadecimal. We don't use isprint() because that can vary from system to system
+(even without the use of locales) and we want the output always to be the same,
+for testing purposes. */
+
+#ifdef EBCDIC
+#define PRINTABLE(c) ((c) >= 64 && (c) < 255)
+#else
+#define PRINTABLE(c) ((c) >= 32 && (c) < 127)
+#endif
+
+/* The table of operator names. */
+
+static const char *priv_OP_names[] = { OP_NAME_LIST };
+
+/* This table of operator lengths is not actually used by the working code,
+but its size is needed for a check that ensures it is the correct size for the
+number of opcodes (thus catching update omissions). */
+
+static const pcre_uint8 priv_OP_lengths[] = { OP_LENGTHS };
+
+
+
+/*************************************************
+* Print single- or multi-byte character *
+*************************************************/
+
+static int
+print_char(FILE *f, pcre_uchar *ptr, BOOL utf)
+{
+int c = *ptr;
+
+#ifndef SUPPORT_UTF
+
+(void)utf; /* Avoid compiler warning */
+if (PRINTABLE(c)) fprintf(f, "%c", c);
+else if (c <= 0xff) fprintf(f, "\\x%02x", c);
+else fprintf(f, "\\x{%x}", c);
+return 0;
+
+#else
+
+#ifdef COMPILE_PCRE8
+
+if (!utf || (c & 0xc0) != 0xc0)
+ {
+ if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
+ return 0;
+ }
+else
+ {
+ int i;
+ int a = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */
+ int s = 6*a;
+ c = (c & PRIV(utf8_table3)[a]) << s;
+ for (i = 1; i <= a; i++)
+ {
+ /* This is a check for malformed UTF-8; it should only occur if the sanity
+ check has been turned off. Rather than swallow random bytes, just stop if
+ we hit a bad one. Print it with \X instead of \x as an indication. */
+
+ if ((ptr[i] & 0xc0) != 0x80)
+ {
+ fprintf(f, "\\X{%x}", c);
+ return i - 1;
+ }
+
+ /* The byte is OK */
+
+ s -= 6;
+ c |= (ptr[i] & 0x3f) << s;
+ }
+ fprintf(f, "\\x{%x}", c);
+ return a;
+ }
+
+#else
+
+#ifdef COMPILE_PCRE16
+
+if (!utf || (c & 0xfc00) != 0xd800)
+ {
+ if (PRINTABLE(c)) fprintf(f, "%c", c);
+ else if (c <= 0xff) fprintf(f, "\\x%02x", c);
+ else fprintf(f, "\\x{%x}", c);
+ return 0;
+ }
+else
+ {
+ /* This is a check for malformed UTF-16; it should only occur if the sanity
+ check has been turned off. Rather than swallow a low surrogate, just stop if
+ we hit a bad one. Print it with \X instead of \x as an indication. */
+
+ if ((ptr[1] & 0xfc00) != 0xdc00)
+ {
+ fprintf(f, "\\X{%x}", c);
+ return 0;
+ }
+
+ c = (((c & 0x3ff) << 10) | (ptr[1] & 0x3ff)) + 0x10000;
+ fprintf(f, "\\x{%x}", c);
+ return 1;
+ }
+
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+
+#endif /* SUPPORT_UTF */
+}
+
+/*************************************************
+* Print uchar string (regardless of utf) *
+*************************************************/
+
+static void
+print_puchar(FILE *f, PCRE_PUCHAR ptr)
+{
+while (*ptr != '\0')
+ {
+ register int c = *ptr++;
+ if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);
+ }
+}
+
+/*************************************************
+* Find Unicode property name *
+*************************************************/
+
+static const char *
+get_ucpname(int ptype, int pvalue)
+{
+#ifdef SUPPORT_UCP
+int i;
+for (i = PRIV(utt_size) - 1; i >= 0; i--)
+ {
+ if (ptype == PRIV(utt)[i].type && pvalue == PRIV(utt)[i].value) break;
+ }
+return (i >= 0)? PRIV(utt_names) + PRIV(utt)[i].name_offset : "??";
+#else
+/* It gets harder and harder to shut off unwanted compiler warnings. */
+ptype = ptype * pvalue;
+return (ptype == pvalue)? "??" : "??";
+#endif
+}
+
+
+
+/*************************************************
+* Print compiled regex *
+*************************************************/
+
+/* Make this function work for a regex with integers either byte order.
+However, we assume that what we are passed is a compiled regex. The
+print_lengths flag controls whether offsets and lengths of items are printed.
+They can be turned off from pcretest so that automatic tests on bytecode can be
+written that do not depend on the value of LINK_SIZE. */
+
+#ifdef PCRE_INCLUDED
+static /* Keep the following function as private. */
+#endif
+#ifdef COMPILE_PCRE8
+void
+pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
+#else
+void
+pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths)
+#endif
+{
+REAL_PCRE *re = (REAL_PCRE *)external_re;
+pcre_uchar *codestart, *code;
+BOOL utf;
+
+unsigned int options = re->options;
+int offset = re->name_table_offset;
+int count = re->name_count;
+int size = re->name_entry_size;
+
+if (re->magic_number != MAGIC_NUMBER)
+ {
+ offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff);
+ count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff);
+ size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff);
+ options = ((options << 24) & 0xff000000) |
+ ((options << 8) & 0x00ff0000) |
+ ((options >> 8) & 0x0000ff00) |
+ ((options >> 24) & 0x000000ff);
+ }
+
+code = codestart = (pcre_uchar *)re + offset + count * size;
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+utf = (options & PCRE_UTF8) != 0;
+
+for(;;)
+ {
+ pcre_uchar *ccode;
+ const char *flag = " ";
+ int c;
+ int extra = 0;
+
+ if (print_lengths)
+ fprintf(f, "%3d ", (int)(code - codestart));
+ else
+ fprintf(f, " ");
+
+ switch(*code)
+ {
+/* ========================================================================== */
+ /* These cases are never obeyed. This is a fudge that causes a compile-
+ time error if the vectors OP_names or OP_lengths, which are indexed
+ by opcode, are not the correct length. It seems to be the only way to do
+ such a check at compile time, as the sizeof() operator does not work in
+ the C preprocessor. */
+
+ case OP_TABLE_LENGTH:
+ case OP_TABLE_LENGTH +
+ ((sizeof(priv_OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) &&
+ (sizeof(priv_OP_lengths) == OP_TABLE_LENGTH)):
+ break;
+/* ========================================================================== */
+
+ case OP_END:
+ fprintf(f, " %s\n", priv_OP_names[*code]);
+ fprintf(f, "------------------------------------------------------------------\n");
+ return;
+
+ case OP_CHAR:
+ fprintf(f, " ");
+ do
+ {
+ code++;
+ code += 1 + print_char(f, code, utf);
+ }
+ while (*code == OP_CHAR);
+ fprintf(f, "\n");
+ continue;
+
+ case OP_CHARI:
+ fprintf(f, " /i ");
+ do
+ {
+ code++;
+ code += 1 + print_char(f, code, utf);
+ }
+ while (*code == OP_CHARI);
+ fprintf(f, "\n");
+ continue;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
+ else fprintf(f, " ");
+ fprintf(f, "%s %d", priv_OP_names[*code], GET2(code, 1+LINK_SIZE));
+ break;
+
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_ALT:
+ case OP_KET:
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_COND:
+ case OP_SCOND:
+ case OP_REVERSE:
+ if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
+ else fprintf(f, " ");
+ fprintf(f, "%s", priv_OP_names[*code]);
+ break;
+
+ case OP_CLOSE:
+ fprintf(f, " %s %d", priv_OP_names[*code], GET2(code, 1));
+ break;
+
+ case OP_CREF:
+ case OP_NCREF:
+ fprintf(f, "%3d %s", GET2(code,1), priv_OP_names[*code]);
+ break;
+
+ case OP_RREF:
+ c = GET2(code, 1);
+ if (c == RREF_ANY)
+ fprintf(f, " Cond recurse any");
+ else
+ fprintf(f, " Cond recurse %d", c);
+ break;
+
+ case OP_NRREF:
+ c = GET2(code, 1);
+ if (c == RREF_ANY)
+ fprintf(f, " Cond nrecurse any");
+ else
+ fprintf(f, " Cond nrecurse %d", c);
+ break;
+
+ case OP_DEF:
+ fprintf(f, " Cond def");
+ break;
+
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_POSSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ flag = "/i";
+ /* Fall through */
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_POSSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSQUERY:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSQUERY:
+ fprintf(f, " %s ", flag);
+ if (*code >= OP_TYPESTAR)
+ {
+ fprintf(f, "%s", priv_OP_names[code[1]]);
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
+ {
+ fprintf(f, " %s ", get_ucpname(code[2], code[3]));
+ extra = 2;
+ }
+ }
+ else extra = print_char(f, code+1, utf);
+ fprintf(f, "%s", priv_OP_names[*code]);
+ break;
+
+ case OP_EXACTI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_POSUPTOI:
+ flag = "/i";
+ /* Fall through */
+ case OP_EXACT:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_POSUPTO:
+ fprintf(f, " %s ", flag);
+ extra = print_char(f, code + 1 + IMM2_SIZE, utf);
+ fprintf(f, "{");
+ if (*code != OP_EXACT && *code != OP_EXACTI) fprintf(f, "0,");
+ fprintf(f, "%d}", GET2(code,1));
+ if (*code == OP_MINUPTO || *code == OP_MINUPTOI) fprintf(f, "?");
+ else if (*code == OP_POSUPTO || *code == OP_POSUPTOI) fprintf(f, "+");
+ break;
+
+ case OP_TYPEEXACT:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ fprintf(f, " %s", priv_OP_names[code[1 + IMM2_SIZE]]);
+ if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
+ {
+ fprintf(f, " %s ", get_ucpname(code[1 + IMM2_SIZE + 1],
+ code[1 + IMM2_SIZE + 2]));
+ extra = 2;
+ }
+ fprintf(f, "{");
+ if (*code != OP_TYPEEXACT) fprintf(f, "0,");
+ fprintf(f, "%d}", GET2(code,1));
+ if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
+ else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
+ break;
+
+ case OP_NOTI:
+ flag = "/i";
+ /* Fall through */
+ case OP_NOT:
+ fprintf(f, " %s [^", flag);
+ extra = print_char(f, code + 1, utf);
+ fprintf(f, "]");
+ break;
+
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTPOSQUERYI:
+ flag = "/i";
+ /* Fall through */
+
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTPOSPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTPOSQUERY:
+ fprintf(f, " %s [^", flag);
+ extra = print_char(f, code + 1, utf);
+ fprintf(f, "]%s", priv_OP_names[*code]);
+ break;
+
+ case OP_NOTEXACTI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPOSUPTOI:
+ flag = "/i";
+ /* Fall through */
+
+ case OP_NOTEXACT:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTPOSUPTO:
+ fprintf(f, " %s [^", flag);
+ extra = print_char(f, code + 1 + IMM2_SIZE, utf);
+ fprintf(f, "]{");
+ if (*code != OP_NOTEXACT && *code != OP_NOTEXACTI) fprintf(f, "0,");
+ fprintf(f, "%d}", GET2(code,1));
+ if (*code == OP_NOTMINUPTO || *code == OP_NOTMINUPTOI) fprintf(f, "?");
+ else
+ if (*code == OP_NOTPOSUPTO || *code == OP_NOTPOSUPTOI) fprintf(f, "+");
+ break;
+
+ case OP_RECURSE:
+ if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
+ else fprintf(f, " ");
+ fprintf(f, "%s", priv_OP_names[*code]);
+ break;
+
+ case OP_REFI:
+ flag = "/i";
+ /* Fall through */
+ case OP_REF:
+ fprintf(f, " %s \\%d", flag, GET2(code,1));
+ ccode = code + priv_OP_lengths[*code];
+ goto CLASS_REF_REPEAT;
+
+ case OP_CALLOUT:
+ fprintf(f, " %s %d %d %d", priv_OP_names[*code], code[1], GET(code,2),
+ GET(code, 2 + LINK_SIZE));
+ break;
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ fprintf(f, " %s %s", priv_OP_names[*code], get_ucpname(code[1], code[2]));
+ break;
+
+ /* OP_XCLASS can only occur in UTF or PCRE16 modes. However, there's no
+ harm in having this code always here, and it makes it less messy without
+ all those #ifdefs. */
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ case OP_XCLASS:
+ {
+ int i, min, max;
+ BOOL printmap;
+ pcre_uint8 *map;
+
+ fprintf(f, " [");
+
+ if (*code == OP_XCLASS)
+ {
+ extra = GET(code, 1);
+ ccode = code + LINK_SIZE + 1;
+ printmap = (*ccode & XCL_MAP) != 0;
+ if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^");
+ }
+ else
+ {
+ printmap = TRUE;
+ ccode = code + 1;
+ }
+
+ /* Print a bit map */
+
+ if (printmap)
+ {
+ map = (pcre_uint8 *)ccode;
+ for (i = 0; i < 256; i++)
+ {
+ if ((map[i/8] & (1 << (i&7))) != 0)
+ {
+ int j;
+ for (j = i+1; j < 256; j++)
+ if ((map[j/8] & (1 << (j&7))) == 0) break;
+ if (i == '-' || i == ']') fprintf(f, "\\");
+ if (PRINTABLE(i)) fprintf(f, "%c", i);
+ else fprintf(f, "\\x%02x", i);
+ if (--j > i)
+ {
+ if (j != i + 1) fprintf(f, "-");
+ if (j == '-' || j == ']') fprintf(f, "\\");
+ if (PRINTABLE(j)) fprintf(f, "%c", j);
+ else fprintf(f, "\\x%02x", j);
+ }
+ i = j;
+ }
+ }
+ ccode += 32 / sizeof(pcre_uchar);
+ }
+
+ /* For an XCLASS there is always some additional data */
+
+ if (*code == OP_XCLASS)
+ {
+ int ch;
+ while ((ch = *ccode++) != XCL_END)
+ {
+ if (ch == XCL_PROP)
+ {
+ int ptype = *ccode++;
+ int pvalue = *ccode++;
+ fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue));
+ }
+ else if (ch == XCL_NOTPROP)
+ {
+ int ptype = *ccode++;
+ int pvalue = *ccode++;
+ fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue));
+ }
+ else
+ {
+ ccode += 1 + print_char(f, ccode, utf);
+ if (ch == XCL_RANGE)
+ {
+ fprintf(f, "-");
+ ccode += 1 + print_char(f, ccode, utf);
+ }
+ }
+ }
+ }
+
+ /* Indicate a non-UTF class which was created by negation */
+
+ fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
+
+ /* Handle repeats after a class or a back reference */
+
+ CLASS_REF_REPEAT:
+ switch(*ccode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ fprintf(f, "%s", priv_OP_names[*ccode]);
+ extra += priv_OP_lengths[*ccode];
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ min = GET2(ccode,1);
+ max = GET2(ccode,1 + IMM2_SIZE);
+ if (max == 0) fprintf(f, "{%d,}", min);
+ else fprintf(f, "{%d,%d}", min, max);
+ if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
+ extra += priv_OP_lengths[*ccode];
+ break;
+
+ /* Do nothing if it's not a repeat; this code stops picky compilers
+ warning about the lack of a default code path. */
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ fprintf(f, " %s ", priv_OP_names[*code]);
+ print_puchar(f, code + 2);
+ extra += code[1];
+ break;
+
+ case OP_THEN:
+ fprintf(f, " %s", priv_OP_names[*code]);
+ break;
+
+ case OP_CIRCM:
+ case OP_DOLLM:
+ flag = "/m";
+ /* Fall through */
+
+ /* Anything else is just an item with no data, but possibly a flag. */
+
+ default:
+ fprintf(f, " %s %s", flag, priv_OP_names[*code]);
+ break;
+ }
+
+ code += priv_OP_lengths[*code] + extra;
+ fprintf(f, "\n");
+ }
+}
+
+/* End of pcre_printint.src */
diff -Nru pcre3-8.12/pcre_printint.src pcre3-8.31/pcre_printint.src
--- pcre3-8.12/pcre_printint.src 2010-11-24 17:38:32.000000000 +0000
+++ pcre3-8.31/pcre_printint.src 1970-01-01 00:00:00.000000000 +0000
@@ -1,572 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2010 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains a PCRE private debugging function for printing out the
-internal form of a compiled regular expression, along with some supporting
-local functions. This source file is used in two places:
-
-(1) It is #included by pcre_compile.c when it is compiled in debugging mode
-(PCRE_DEBUG defined in pcre_internal.h). It is not included in production
-compiles.
-
-(2) It is always #included by pcretest.c, which can be asked to print out a
-compiled regex for debugging purposes. */
-
-
-/* Macro that decides whether a character should be output as a literal or in
-hexadecimal. We don't use isprint() because that can vary from system to system
-(even without the use of locales) and we want the output always to be the same,
-for testing purposes. This macro is used in pcretest as well as in this file. */
-
-#ifdef EBCDIC
-#define PRINTABLE(c) ((c) >= 64 && (c) < 255)
-#else
-#define PRINTABLE(c) ((c) >= 32 && (c) < 127)
-#endif
-
-/* The table of operator names. */
-
-static const char *OP_names[] = { OP_NAME_LIST };
-
-
-
-/*************************************************
-* Print single- or multi-byte character *
-*************************************************/
-
-static int
-print_char(FILE *f, uschar *ptr, BOOL utf8)
-{
-int c = *ptr;
-
-#ifndef SUPPORT_UTF8
-utf8 = utf8; /* Avoid compiler warning */
-if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
-return 0;
-
-#else
-if (!utf8 || (c & 0xc0) != 0xc0)
- {
- if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
- return 0;
- }
-else
- {
- int i;
- int a = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */
- int s = 6*a;
- c = (c & _pcre_utf8_table3[a]) << s;
- for (i = 1; i <= a; i++)
- {
- /* This is a check for malformed UTF-8; it should only occur if the sanity
- check has been turned off. Rather than swallow random bytes, just stop if
- we hit a bad one. Print it with \X instead of \x as an indication. */
-
- if ((ptr[i] & 0xc0) != 0x80)
- {
- fprintf(f, "\\X{%x}", c);
- return i - 1;
- }
-
- /* The byte is OK */
-
- s -= 6;
- c |= (ptr[i] & 0x3f) << s;
- }
- if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c);
- return a;
- }
-#endif
-}
-
-
-
-/*************************************************
-* Find Unicode property name *
-*************************************************/
-
-static const char *
-get_ucpname(int ptype, int pvalue)
-{
-#ifdef SUPPORT_UCP
-int i;
-for (i = _pcre_utt_size - 1; i >= 0; i--)
- {
- if (ptype == _pcre_utt[i].type && pvalue == _pcre_utt[i].value) break;
- }
-return (i >= 0)? _pcre_utt_names + _pcre_utt[i].name_offset : "??";
-#else
-/* It gets harder and harder to shut off unwanted compiler warnings. */
-ptype = ptype * pvalue;
-return (ptype == pvalue)? "??" : "??";
-#endif
-}
-
-
-
-/*************************************************
-* Print compiled regex *
-*************************************************/
-
-/* Make this function work for a regex with integers either byte order.
-However, we assume that what we are passed is a compiled regex. The
-print_lengths flag controls whether offsets and lengths of items are printed.
-They can be turned off from pcretest so that automatic tests on bytecode can be
-written that do not depend on the value of LINK_SIZE. */
-
-static void
-pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
-{
-real_pcre *re = (real_pcre *)external_re;
-uschar *codestart, *code;
-BOOL utf8;
-
-unsigned int options = re->options;
-int offset = re->name_table_offset;
-int count = re->name_count;
-int size = re->name_entry_size;
-
-if (re->magic_number != MAGIC_NUMBER)
- {
- offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff);
- count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff);
- size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff);
- options = ((options << 24) & 0xff000000) |
- ((options << 8) & 0x00ff0000) |
- ((options >> 8) & 0x0000ff00) |
- ((options >> 24) & 0x000000ff);
- }
-
-code = codestart = (uschar *)re + offset + count * size;
-utf8 = (options & PCRE_UTF8) != 0;
-
-for(;;)
- {
- uschar *ccode;
- int c;
- int extra = 0;
-
- if (print_lengths)
- fprintf(f, "%3d ", (int)(code - codestart));
- else
- fprintf(f, " ");
-
- switch(*code)
- {
-/* ========================================================================== */
- /* These cases are never obeyed. This is a fudge that causes a compile-
- time error if the vectors OP_names or _pcre_OP_lengths, which are indexed
- by opcode, are not the correct length. It seems to be the only way to do
- such a check at compile time, as the sizeof() operator does not work in
- the C preprocessor. We do this while compiling pcretest, because that
- #includes pcre_tables.c, which holds _pcre_OP_lengths. We can't do this
- when building pcre_compile.c with PCRE_DEBUG set, because it doesn't then
- know the size of _pcre_OP_lengths. */
-
-#ifdef COMPILING_PCRETEST
- case OP_TABLE_LENGTH:
- case OP_TABLE_LENGTH +
- ((sizeof(OP_names)/sizeof(const char *) == OP_TABLE_LENGTH) &&
- (sizeof(_pcre_OP_lengths) == OP_TABLE_LENGTH)):
- break;
-#endif
-/* ========================================================================== */
-
- case OP_END:
- fprintf(f, " %s\n", OP_names[*code]);
- fprintf(f, "------------------------------------------------------------------\n");
- return;
-
- case OP_OPT:
- fprintf(f, " %.2x %s", code[1], OP_names[*code]);
- break;
-
- case OP_CHAR:
- fprintf(f, " ");
- do
- {
- code++;
- code += 1 + print_char(f, code, utf8);
- }
- while (*code == OP_CHAR);
- fprintf(f, "\n");
- continue;
-
- case OP_CHARNC:
- fprintf(f, " NC ");
- do
- {
- code++;
- code += 1 + print_char(f, code, utf8);
- }
- while (*code == OP_CHARNC);
- fprintf(f, "\n");
- continue;
-
- case OP_CBRA:
- case OP_SCBRA:
- if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
- else fprintf(f, " ");
- fprintf(f, "%s %d", OP_names[*code], GET2(code, 1+LINK_SIZE));
- break;
-
- case OP_BRA:
- case OP_SBRA:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_ALT:
- case OP_KET:
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- case OP_ONCE:
- case OP_COND:
- case OP_SCOND:
- case OP_REVERSE:
- if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
- else fprintf(f, " ");
- fprintf(f, "%s", OP_names[*code]);
- break;
-
- case OP_CLOSE:
- fprintf(f, " %s %d", OP_names[*code], GET2(code, 1));
- break;
-
- case OP_CREF:
- case OP_NCREF:
- fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);
- break;
-
- case OP_RREF:
- c = GET2(code, 1);
- if (c == RREF_ANY)
- fprintf(f, " Cond recurse any");
- else
- fprintf(f, " Cond recurse %d", c);
- break;
-
- case OP_NRREF:
- c = GET2(code, 1);
- if (c == RREF_ANY)
- fprintf(f, " Cond nrecurse any");
- else
- fprintf(f, " Cond nrecurse %d", c);
- break;
-
- case OP_DEF:
- fprintf(f, " Cond def");
- break;
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- fprintf(f, " ");
- if (*code >= OP_TYPESTAR)
- {
- fprintf(f, "%s", OP_names[code[1]]);
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
- {
- fprintf(f, " %s ", get_ucpname(code[2], code[3]));
- extra = 2;
- }
- }
- else extra = print_char(f, code+1, utf8);
- fprintf(f, "%s", OP_names[*code]);
- break;
-
- case OP_EXACT:
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- fprintf(f, " ");
- extra = print_char(f, code+3, utf8);
- fprintf(f, "{");
- if (*code != OP_EXACT) fprintf(f, "0,");
- fprintf(f, "%d}", GET2(code,1));
- if (*code == OP_MINUPTO) fprintf(f, "?");
- else if (*code == OP_POSUPTO) fprintf(f, "+");
- break;
-
- case OP_TYPEEXACT:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- fprintf(f, " %s", OP_names[code[3]]);
- if (code[3] == OP_PROP || code[3] == OP_NOTPROP)
- {
- fprintf(f, " %s ", get_ucpname(code[4], code[5]));
- extra = 2;
- }
- fprintf(f, "{");
- if (*code != OP_TYPEEXACT) fprintf(f, "0,");
- fprintf(f, "%d}", GET2(code,1));
- if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
- else if (*code == OP_TYPEPOSUPTO) fprintf(f, "+");
- break;
-
- case OP_NOT:
- c = code[1];
- if (PRINTABLE(c)) fprintf(f, " [^%c]", c);
- else fprintf(f, " [^\\x%02x]", c);
- break;
-
- case OP_NOTSTAR:
- case OP_NOTMINSTAR:
- case OP_NOTPOSSTAR:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTPOSPLUS:
- case OP_NOTQUERY:
- case OP_NOTMINQUERY:
- case OP_NOTPOSQUERY:
- c = code[1];
- if (PRINTABLE(c)) fprintf(f, " [^%c]", c);
- else fprintf(f, " [^\\x%02x]", c);
- fprintf(f, "%s", OP_names[*code]);
- break;
-
- case OP_NOTEXACT:
- case OP_NOTUPTO:
- case OP_NOTMINUPTO:
- case OP_NOTPOSUPTO:
- c = code[3];
- if (PRINTABLE(c)) fprintf(f, " [^%c]{", c);
- else fprintf(f, " [^\\x%02x]{", c);
- if (*code != OP_NOTEXACT) fprintf(f, "0,");
- fprintf(f, "%d}", GET2(code,1));
- if (*code == OP_NOTMINUPTO) fprintf(f, "?");
- else if (*code == OP_NOTPOSUPTO) fprintf(f, "+");
- break;
-
- case OP_RECURSE:
- if (print_lengths) fprintf(f, "%3d ", GET(code, 1));
- else fprintf(f, " ");
- fprintf(f, "%s", OP_names[*code]);
- break;
-
- case OP_REF:
- fprintf(f, " \\%d", GET2(code,1));
- ccode = code + _pcre_OP_lengths[*code];
- goto CLASS_REF_REPEAT;
-
- case OP_CALLOUT:
- fprintf(f, " %s %d %d %d", OP_names[*code], code[1], GET(code,2),
- GET(code, 2 + LINK_SIZE));
- break;
-
- case OP_PROP:
- case OP_NOTPROP:
- fprintf(f, " %s %s", OP_names[*code], get_ucpname(code[1], code[2]));
- break;
-
- /* OP_XCLASS can only occur in UTF-8 mode. However, there's no harm in
- having this code always here, and it makes it less messy without all those
- #ifdefs. */
-
- case OP_CLASS:
- case OP_NCLASS:
- case OP_XCLASS:
- {
- int i, min, max;
- BOOL printmap;
-
- fprintf(f, " [");
-
- if (*code == OP_XCLASS)
- {
- extra = GET(code, 1);
- ccode = code + LINK_SIZE + 1;
- printmap = (*ccode & XCL_MAP) != 0;
- if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^");
- }
- else
- {
- printmap = TRUE;
- ccode = code + 1;
- }
-
- /* Print a bit map */
-
- if (printmap)
- {
- for (i = 0; i < 256; i++)
- {
- if ((ccode[i/8] & (1 << (i&7))) != 0)
- {
- int j;
- for (j = i+1; j < 256; j++)
- if ((ccode[j/8] & (1 << (j&7))) == 0) break;
- if (i == '-' || i == ']') fprintf(f, "\\");
- if (PRINTABLE(i)) fprintf(f, "%c", i);
- else fprintf(f, "\\x%02x", i);
- if (--j > i)
- {
- if (j != i + 1) fprintf(f, "-");
- if (j == '-' || j == ']') fprintf(f, "\\");
- if (PRINTABLE(j)) fprintf(f, "%c", j);
- else fprintf(f, "\\x%02x", j);
- }
- i = j;
- }
- }
- ccode += 32;
- }
-
- /* For an XCLASS there is always some additional data */
-
- if (*code == OP_XCLASS)
- {
- int ch;
- while ((ch = *ccode++) != XCL_END)
- {
- if (ch == XCL_PROP)
- {
- int ptype = *ccode++;
- int pvalue = *ccode++;
- fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue));
- }
- else if (ch == XCL_NOTPROP)
- {
- int ptype = *ccode++;
- int pvalue = *ccode++;
- fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue));
- }
- else
- {
- ccode += 1 + print_char(f, ccode, TRUE);
- if (ch == XCL_RANGE)
- {
- fprintf(f, "-");
- ccode += 1 + print_char(f, ccode, TRUE);
- }
- }
- }
- }
-
- /* Indicate a non-UTF8 class which was created by negation */
-
- fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
-
- /* Handle repeats after a class or a back reference */
-
- CLASS_REF_REPEAT:
- switch(*ccode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- fprintf(f, "%s", OP_names[*ccode]);
- extra += _pcre_OP_lengths[*ccode];
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- min = GET2(ccode,1);
- max = GET2(ccode,3);
- if (max == 0) fprintf(f, "{%d,}", min);
- else fprintf(f, "{%d,%d}", min, max);
- if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
- extra += _pcre_OP_lengths[*ccode];
- break;
-
- /* Do nothing if it's not a repeat; this code stops picky compilers
- warning about the lack of a default code path. */
-
- default:
- break;
- }
- }
- break;
-
- case OP_MARK:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- fprintf(f, " %s %s", OP_names[*code], code + 2);
- extra += code[1];
- break;
-
- case OP_THEN:
- if (print_lengths)
- fprintf(f, " %s %d", OP_names[*code], GET(code, 1));
- else
- fprintf(f, " %s", OP_names[*code]);
- break;
-
- case OP_THEN_ARG:
- if (print_lengths)
- fprintf(f, " %s %d %s", OP_names[*code], GET(code, 1),
- code + 2 + LINK_SIZE);
- else
- fprintf(f, " %s %s", OP_names[*code], code + 2 + LINK_SIZE);
- extra += code[1+LINK_SIZE];
- break;
-
- /* Anything else is just an item with no data*/
-
- default:
- fprintf(f, " %s", OP_names[*code]);
- break;
- }
-
- code += _pcre_OP_lengths[*code] + extra;
- fprintf(f, "\n");
- }
-}
-
-/* End of pcre_printint.src */
diff -Nru pcre3-8.12/pcre_refcount.c pcre3-8.31/pcre_refcount.c
--- pcre3-8.12/pcre_refcount.c 2008-07-09 15:52:45.000000000 +0000
+++ pcre3-8.31/pcre_refcount.c 2012-01-06 12:50:34.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -68,11 +68,18 @@
a negative error number
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_refcount(pcre *argument_re, int adjust)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_refcount(pcre16 *argument_re, int adjust)
+#endif
{
-real_pcre *re = (real_pcre *)argument_re;
+REAL_PCRE *re = (REAL_PCRE *)argument_re;
if (re == NULL) return PCRE_ERROR_NULL;
+if (re->magic_number != MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
re->ref_count = (-adjust > re->ref_count)? 0 :
(adjust + re->ref_count > 65535)? 65535 :
re->ref_count + adjust;
diff -Nru pcre3-8.12/pcre_scanner_unittest.cc pcre3-8.31/pcre_scanner_unittest.cc
--- pcre3-8.12/pcre_scanner_unittest.cc 2010-06-01 11:44:28.000000000 +0000
+++ pcre3-8.31/pcre_scanner_unittest.cc 2011-05-01 08:16:45.000000000 +0000
@@ -37,6 +37,7 @@
#endif
#include
+#include /* for strchr */
#include
#include
diff -Nru pcre3-8.12/pcre_string_utils.c pcre3-8.31/pcre_string_utils.c
--- pcre3-8.12/pcre_string_utils.c 1970-01-01 00:00:00.000000000 +0000
+++ pcre3-8.31/pcre_string_utils.c 2011-12-28 16:57:56.000000000 +0000
@@ -0,0 +1,168 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function that is used to match an extended
+class. It is used by both pcre_exec() and pcre_def_exec(). */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#ifndef COMPILE_PCRE8
+
+/*************************************************
+* Compare string utilities *
+*************************************************/
+
+/* The following two functions compares two strings. Basically an strcmp
+for non 8 bit characters.
+
+Arguments:
+ str1 first string
+ str2 second string
+
+Returns: 0 if both string are equal (like strcmp), 1 otherwise
+*/
+
+int
+PRIV(strcmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2)
+{
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (*str1 != '\0' || *str2 != '\0')
+ {
+ c1 = *str1++;
+ c2 = *str2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+int
+PRIV(strcmp_uc_c8)(const pcre_uchar *str1, const char *str2)
+{
+const pcre_uint8 *ustr2 = (pcre_uint8 *)str2;
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (*str1 != '\0' || *ustr2 != '\0')
+ {
+ c1 = *str1++;
+ c2 = (pcre_uchar)*ustr2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+/* The following two functions compares two, fixed length
+strings. Basically an strncmp for non 8 bit characters.
+
+Arguments:
+ str1 first string
+ str2 second string
+ num size of the string
+
+Returns: 0 if both string are equal (like strcmp), 1 otherwise
+*/
+
+int
+PRIV(strncmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2, unsigned int num)
+{
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (num-- > 0)
+ {
+ c1 = *str1++;
+ c2 = *str2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+int
+PRIV(strncmp_uc_c8)(const pcre_uchar *str1, const char *str2, unsigned int num)
+{
+const pcre_uint8 *ustr2 = (pcre_uint8 *)str2;
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (num-- > 0)
+ {
+ c1 = *str1++;
+ c2 = (pcre_uchar)*ustr2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+/* The following function returns with the length of
+a zero terminated string. Basically an strlen for non 8 bit characters.
+
+Arguments:
+ str string
+
+Returns: length of the string
+*/
+
+unsigned int
+PRIV(strlen_uc)(const pcre_uchar *str)
+{
+unsigned int len = 0;
+while (*str++ != 0)
+ len++;
+return len;
+}
+
+#endif /* COMPILE_PCRE8 */
+
+/* End of pcre_string_utils.c */
diff -Nru pcre3-8.12/pcre_study.c pcre3-8.31/pcre_study.c
--- pcre3-8.12/pcre_study.c 2010-10-27 16:36:01.000000000 +0000
+++ pcre3-8.31/pcre_study.c 2012-07-06 08:51:36.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2010 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -52,7 +52,7 @@
/* Returns from set_start_bits() */
-enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE };
+enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN };
@@ -66,25 +66,30 @@
rather than bytes.
Arguments:
- code pointer to start of group (the bracket)
- startcode pointer to start of the whole pattern
- options the compiling options
+ code pointer to start of group (the bracket)
+ startcode pointer to start of the whole pattern
+ options the compiling options
+ int RECURSE depth
Returns: the minimum length
- -1 if \C was encountered
+ -1 if \C in UTF-8 mode or (*ACCEPT) was encountered
-2 internal error (missing capturing bracket)
+ -3 internal error (opcode not listed)
*/
static int
-find_minlength(const uschar *code, const uschar *startcode, int options)
+find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options,
+ int recurse_depth)
{
int length = -1;
-BOOL utf8 = (options & PCRE_UTF8) != 0;
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+BOOL utf = (options & PCRE_UTF8) != 0;
BOOL had_recurse = FALSE;
register int branchlength = 0;
-register uschar *cc = (uschar *)code + 1 + LINK_SIZE;
+register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE;
-if (*code == OP_CBRA || *code == OP_SCBRA) cc += 2;
+if (*code == OP_CBRA || *code == OP_SCBRA ||
+ *code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE;
/* Scan along the opcodes for this branch. If we get to the end of the
branch, check the length against that of the other branches. */
@@ -92,7 +97,7 @@
for (;;)
{
int d, min;
- uschar *cs, *ce;
+ pcre_uchar *cs, *ce;
register int op = *cc;
switch (op)
@@ -118,26 +123,40 @@
case OP_SCBRA:
case OP_BRA:
case OP_SBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
case OP_ONCE:
- d = find_minlength(cc, startcode, options);
+ case OP_ONCE_NC:
+ d = find_minlength(cc, startcode, options, recurse_depth);
if (d < 0) return d;
branchlength += d;
do cc += GET(cc, 1); while (*cc == OP_ALT);
cc += 1 + LINK_SIZE;
break;
+ /* ACCEPT makes things far too complicated; we have to give up. */
+
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ return -1;
+
/* Reached end of a branch; if it's a ket it is the end of a nested
- call. If it's ALT it is an alternation in a nested call. If it is
- END it's the end of the outer call. All can be handled by the same code. */
+ call. If it's ALT it is an alternation in a nested call. If it is END it's
+ the end of the outer call. All can be handled by the same code. If an
+ ACCEPT was previously encountered, use the length that was in force at that
+ time, and pass back the shortest ACCEPT length. */
case OP_ALT:
case OP_KET:
case OP_KETRMAX:
case OP_KETRMIN:
+ case OP_KETRPOS:
case OP_END:
if (length < 0 || (!had_recurse && branchlength < length))
length = branchlength;
- if (*cc != OP_ALT) return length;
+ if (op != OP_ALT) return length;
cc += 1 + LINK_SIZE;
branchlength = 0;
had_recurse = FALSE;
@@ -160,25 +179,27 @@
case OP_RREF:
case OP_NRREF:
case OP_DEF:
- case OP_OPT:
case OP_CALLOUT:
case OP_SOD:
case OP_SOM:
case OP_EOD:
case OP_EODN:
case OP_CIRC:
+ case OP_CIRCM:
case OP_DOLL:
+ case OP_DOLLM:
case OP_NOT_WORD_BOUNDARY:
case OP_WORD_BOUNDARY:
- cc += _pcre_OP_lengths[*cc];
+ cc += PRIV(OP_lengths)[*cc];
break;
/* Skip over a subpattern that has a {0} or {0,x} quantifier */
case OP_BRAZERO:
case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
case OP_SKIPZERO:
- cc += _pcre_OP_lengths[*cc];
+ cc += PRIV(OP_lengths)[*cc];
do cc += GET(cc, 1); while (*cc == OP_ALT);
cc += 1 + LINK_SIZE;
break;
@@ -186,18 +207,25 @@
/* Handle literal characters and + repetitions */
case OP_CHAR:
- case OP_CHARNC:
+ case OP_CHARI:
case OP_NOT:
+ case OP_NOTI:
case OP_PLUS:
+ case OP_PLUSI:
case OP_MINPLUS:
+ case OP_MINPLUSI:
case OP_POSPLUS:
+ case OP_POSPLUSI:
case OP_NOTPLUS:
+ case OP_NOTPLUSI:
case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
branchlength++;
cc += 2;
-#ifdef SUPPORT_UTF8
- if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
#endif
break;
@@ -212,17 +240,20 @@
need to skip over a multibyte character in UTF8 mode. */
case OP_EXACT:
+ case OP_EXACTI:
case OP_NOTEXACT:
+ case OP_NOTEXACTI:
branchlength += GET2(cc,1);
- cc += 4;
-#ifdef SUPPORT_UTF8
- if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
#endif
break;
case OP_TYPEEXACT:
branchlength += GET2(cc,1);
- cc += (cc[3] == OP_PROP || cc[3] == OP_NOTPROP)? 6 : 4;
+ cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP
+ || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
break;
/* Handle single-char non-literal matchers */
@@ -249,18 +280,21 @@
cc++;
break;
- /* "Any newline" might match two characters */
+ /* "Any newline" might match two characters, but it also might match just
+ one. */
case OP_ANYNL:
- branchlength += 2;
+ branchlength += 1;
cc++;
break;
- /* The single-byte matcher means we can't proceed in UTF-8 mode */
+ /* The single-byte matcher means we can't proceed in UTF-8 mode. (In
+ non-UTF-8 mode \C will actually be turned into OP_ALLANY, so won't ever
+ appear, but leave the code, just in case.) */
case OP_ANYBYTE:
-#ifdef SUPPORT_UTF8
- if (utf8) return -1;
+#ifdef SUPPORT_UTF
+ if (utf) return -1;
#endif
branchlength++;
cc++;
@@ -276,27 +310,28 @@
case OP_TYPEPOSSTAR:
case OP_TYPEPOSQUERY:
if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2;
- cc += _pcre_OP_lengths[op];
+ cc += PRIV(OP_lengths)[op];
break;
case OP_TYPEUPTO:
case OP_TYPEMINUPTO:
case OP_TYPEPOSUPTO:
- if (cc[3] == OP_PROP || cc[3] == OP_NOTPROP) cc += 2;
- cc += _pcre_OP_lengths[op];
+ if (cc[1 + IMM2_SIZE] == OP_PROP
+ || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;
+ cc += PRIV(OP_lengths)[op];
break;
/* Check a class for variable quantification */
-#ifdef SUPPORT_UTF8
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
case OP_XCLASS:
- cc += GET(cc, 1) - 33;
+ cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS];
/* Fall through */
#endif
case OP_CLASS:
case OP_NCLASS:
- cc += 33;
+ cc += PRIV(OP_lengths)[OP_CLASS];
switch (*cc)
{
@@ -315,7 +350,7 @@
case OP_CRRANGE:
case OP_CRMINRANGE:
branchlength += GET2(cc,1);
- cc += 5;
+ cc += 1 + 2 * IMM2_SIZE;
break;
default:
@@ -337,9 +372,10 @@
that case we must set the minimum length to zero. */
case OP_REF:
+ case OP_REFI:
if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
{
- ce = cs = (uschar *)_pcre_find_bracket(startcode, utf8, GET2(cc, 1));
+ ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1));
if (cs == NULL) return -2;
do ce += GET(ce, 1); while (*ce == OP_ALT);
if (cc > cs && cc < ce)
@@ -347,10 +383,13 @@
d = 0;
had_recurse = TRUE;
}
- else d = find_minlength(cs, startcode, options);
+ else
+ {
+ d = find_minlength(cs, startcode, options, recurse_depth);
+ }
}
else d = 0;
- cc += 3;
+ cc += 1 + IMM2_SIZE;
/* Handle repeated back references */
@@ -364,10 +403,16 @@
cc++;
break;
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ min = 1;
+ cc++;
+ break;
+
case OP_CRRANGE:
case OP_CRMINRANGE:
min = GET2(cc, 1);
- cc += 5;
+ cc += 1 + 2 * IMM2_SIZE;
break;
default:
@@ -378,39 +423,71 @@
branchlength += min * d;
break;
+ /* We can easily detect direct recursion, but not mutual recursion. This is
+ caught by a recursion depth count. */
+
case OP_RECURSE:
- cs = ce = (uschar *)startcode + GET(cc, 1);
- if (cs == NULL) return -2;
+ cs = ce = (pcre_uchar *)startcode + GET(cc, 1);
do ce += GET(ce, 1); while (*ce == OP_ALT);
- if (cc > cs && cc < ce)
+ if ((cc > cs && cc < ce) || recurse_depth > 10)
had_recurse = TRUE;
else
- branchlength += find_minlength(cs, startcode, options);
+ {
+ branchlength += find_minlength(cs, startcode, options, recurse_depth + 1);
+ }
cc += 1 + LINK_SIZE;
break;
/* Anything else does not or need not match a character. We can get the
item's length from the table, but for those that can match zero occurrences
- of a character, we must take special action for UTF-8 characters. */
+ of a character, we must take special action for UTF-8 characters. As it
+ happens, the "NOT" versions of these opcodes are used at present only for
+ ASCII characters, so they could be omitted from this list. However, in
+ future that may change, so we include them here so as not to leave a
+ gotcha for a future maintainer. */
case OP_UPTO:
+ case OP_UPTOI:
case OP_NOTUPTO:
+ case OP_NOTUPTOI:
case OP_MINUPTO:
+ case OP_MINUPTOI:
case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+
case OP_STAR:
+ case OP_STARI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
case OP_MINSTAR:
+ case OP_MINSTARI:
case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
case OP_POSSTAR:
+ case OP_POSSTARI:
case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+
case OP_QUERY:
+ case OP_QUERYI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
case OP_MINQUERY:
+ case OP_MINQUERYI:
case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
case OP_POSQUERY:
+ case OP_POSQUERYI:
case OP_NOTPOSQUERY:
- cc += _pcre_OP_lengths[op];
-#ifdef SUPPORT_UTF8
- if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];
+ case OP_NOTPOSQUERYI:
+
+ cc += PRIV(OP_lengths)[op];
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
#endif
break;
@@ -419,20 +496,27 @@
case OP_MARK:
case OP_PRUNE_ARG:
case OP_SKIP_ARG:
- cc += _pcre_OP_lengths[op] + cc[1];
+ case OP_THEN_ARG:
+ cc += PRIV(OP_lengths)[op] + cc[1];
break;
- case OP_THEN_ARG:
- cc += _pcre_OP_lengths[op] + cc[1+LINK_SIZE];
+ /* The remaining opcodes are just skipped over. */
+
+ case OP_CLOSE:
+ case OP_COMMIT:
+ case OP_FAIL:
+ case OP_PRUNE:
+ case OP_SET_SOM:
+ case OP_SKIP:
+ case OP_THEN:
+ cc += PRIV(OP_lengths)[op];
break;
- /* For the record, these are the opcodes that are matched by "default":
- OP_ACCEPT, OP_CLOSE, OP_COMMIT, OP_FAIL, OP_PRUNE, OP_SET_SOM, OP_SKIP,
- OP_THEN. */
+ /* This should not occur: we list all opcodes explicitly so that when
+ new ones get added they are properly considered. */
default:
- cc += _pcre_OP_lengths[op];
- break;
+ return -3;
}
}
/* Control never gets here */
@@ -454,29 +538,30 @@
p points to the character
caseless the caseless flag
cd the block with char table pointers
- utf8 TRUE for UTF-8 mode
+ utf TRUE for UTF-8 / UTF-16 mode
Returns: pointer after the character
*/
-static const uschar *
-set_table_bit(uschar *start_bits, const uschar *p, BOOL caseless,
- compile_data *cd, BOOL utf8)
+static const pcre_uchar *
+set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless,
+ compile_data *cd, BOOL utf)
{
unsigned int c = *p;
+#ifdef COMPILE_PCRE8
SET_BIT(c);
-#ifdef SUPPORT_UTF8
-if (utf8 && c > 127)
+#ifdef SUPPORT_UTF
+if (utf && c > 127)
{
GETCHARINC(c, p);
#ifdef SUPPORT_UCP
if (caseless)
{
- uschar buff[8];
+ pcre_uchar buff[6];
c = UCD_OTHERCASE(c);
- (void)_pcre_ord2utf8(c, buff);
+ (void)PRIV(ord2utf)(c, buff);
SET_BIT(buff[0]);
}
#endif
@@ -488,6 +573,36 @@
if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
return p + 1;
+#endif
+
+#ifdef COMPILE_PCRE16
+if (c > 0xff)
+ {
+ c = 0xff;
+ caseless = FALSE;
+ }
+SET_BIT(c);
+
+#ifdef SUPPORT_UTF
+if (utf && c > 127)
+ {
+ GETCHARINC(c, p);
+#ifdef SUPPORT_UCP
+ if (caseless)
+ {
+ c = UCD_OTHERCASE(c);
+ if (c > 0xff)
+ c = 0xff;
+ SET_BIT(c);
+ }
+#endif
+ return p;
+ }
+#endif
+
+if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
+return p + 1;
+#endif
}
@@ -513,21 +628,23 @@
*/
static void
-set_type_bits(uschar *start_bits, int cbit_type, int table_limit,
+set_type_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
compile_data *cd)
{
register int c;
for (c = 0; c < table_limit; c++) start_bits[c] |= cd->cbits[c+cbit_type];
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
if (table_limit == 32) return;
for (c = 128; c < 256; c++)
{
if ((cd->cbits[c/8] & (1 << (c&7))) != 0)
{
- uschar buff[8];
- (void)_pcre_ord2utf8(c, buff);
+ pcre_uchar buff[6];
+ (void)PRIV(ord2utf)(c, buff);
SET_BIT(buff[0]);
}
}
+#endif
}
@@ -553,12 +670,14 @@
*/
static void
-set_nottype_bits(uschar *start_bits, int cbit_type, int table_limit,
+set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
compile_data *cd)
{
register int c;
for (c = 0; c < table_limit; c++) start_bits[c] |= ~cd->cbits[c+cbit_type];
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
if (table_limit != 32) for (c = 24; c < 32; c++) start_bits[c] = 0xff;
+#endif
}
@@ -578,22 +697,26 @@
Arguments:
code points to an expression
start_bits points to a 32-byte table, initialized to 0
- caseless the current state of the caseless flag
- utf8 TRUE if in UTF-8 mode
+ utf TRUE if in UTF-8 / UTF-16 mode
cd the block with char table pointers
Returns: SSB_FAIL => Failed to find any starting bytes
SSB_DONE => Found mandatory starting bytes
SSB_CONTINUE => Found optional starting bytes
+ SSB_UNKNOWN => Hit an unrecognized opcode
*/
static int
-set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless,
- BOOL utf8, compile_data *cd)
+set_start_bits(const pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf,
+ compile_data *cd)
{
register int c;
int yield = SSB_DONE;
-int table_limit = utf8? 16:32;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+int table_limit = utf? 16:32;
+#else
+int table_limit = 32;
+#endif
#if 0
/* ========================================================================= */
@@ -614,19 +737,108 @@
do
{
- const uschar *tcode = code + (((int)*code == OP_CBRA)? 3:1) + LINK_SIZE;
BOOL try_next = TRUE;
+ const pcre_uchar *tcode = code + 1 + LINK_SIZE;
+
+ if (*code == OP_CBRA || *code == OP_SCBRA ||
+ *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE;
while (try_next) /* Loop for items in this branch */
{
int rc;
+
switch(*tcode)
{
- /* Fail if we reach something we don't understand */
+ /* If we reach something we don't understand, it means a new opcode has
+ been created that hasn't been added to this code. Hopefully this problem
+ will be discovered during testing. */
default:
+ return SSB_UNKNOWN;
+
+ /* Fail for a valid opcode that implies no starting bits. */
+
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ case OP_ALLANY:
+ case OP_ANY:
+ case OP_ANYBYTE:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_CLOSE:
+ case OP_COMMIT:
+ case OP_COND:
+ case OP_CREF:
+ case OP_DEF:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_END:
+ case OP_EOD:
+ case OP_EODN:
+ case OP_EXTUNI:
+ case OP_FAIL:
+ case OP_MARK:
+ case OP_NCREF:
+ case OP_NOT:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ case OP_NOTI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ case OP_NOTPROP:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_NOT_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_NRREF:
+ case OP_PROP:
+ case OP_PRUNE:
+ case OP_PRUNE_ARG:
+ case OP_RECURSE:
+ case OP_REF:
+ case OP_REFI:
+ case OP_REVERSE:
+ case OP_RREF:
+ case OP_SCOND:
+ case OP_SET_SOM:
+ case OP_SKIP:
+ case OP_SKIP_ARG:
+ case OP_SOD:
+ case OP_SOM:
+ case OP_THEN:
+ case OP_THEN_ARG:
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+#endif
return SSB_FAIL;
+ /* We can ignore word boundary tests. */
+
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_WORD_BOUNDARY:
+ tcode++;
+ break;
+
/* If we hit a bracket or a positive lookahead assertion, recurse to set
bits from within the subpattern. If it can't find anything, we have to
give up. If it finds some mandatory character(s), we are done for this
@@ -636,10 +848,15 @@
case OP_SBRA:
case OP_CBRA:
case OP_SCBRA:
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
case OP_ONCE:
+ case OP_ONCE_NC:
case OP_ASSERT:
- rc = set_start_bits(tcode, start_bits, caseless, utf8, cd);
- if (rc == SSB_FAIL) return SSB_FAIL;
+ rc = set_start_bits(tcode, start_bits, utf, cd);
+ if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
if (rc == SSB_DONE) try_next = FALSE; else
{
do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
@@ -662,6 +879,7 @@
case OP_KET:
case OP_KETRMAX:
case OP_KETRMIN:
+ case OP_KETRPOS:
return SSB_CONTINUE;
/* Skip over callout */
@@ -679,19 +897,13 @@
tcode += 1 + LINK_SIZE;
break;
- /* Skip over an option setting, changing the caseless flag */
-
- case OP_OPT:
- caseless = (tcode[1] & PCRE_CASELESS) != 0;
- tcode += 2;
- break;
-
/* BRAZERO does the bracket, but carries on. */
case OP_BRAZERO:
case OP_BRAMINZERO:
- if (set_start_bits(++tcode, start_bits, caseless, utf8, cd) == SSB_FAIL)
- return SSB_FAIL;
+ case OP_BRAPOSZERO:
+ rc = set_start_bits(++tcode, start_bits, utf, cd);
+ if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
/* =========================================================================
See the comment at the head of this function concerning the next line,
which was an old fudge for the benefit of OS/2.
@@ -717,7 +929,16 @@
case OP_QUERY:
case OP_MINQUERY:
case OP_POSQUERY:
- tcode = set_table_bit(start_bits, tcode + 1, caseless, cd, utf8);
+ tcode = set_table_bit(start_bits, tcode + 1, FALSE, cd, utf);
+ break;
+
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_POSSTARI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ tcode = set_table_bit(start_bits, tcode + 1, TRUE, cd, utf);
break;
/* Single-char upto sets the bit and tries the next */
@@ -725,20 +946,36 @@
case OP_UPTO:
case OP_MINUPTO:
case OP_POSUPTO:
- tcode = set_table_bit(start_bits, tcode + 3, caseless, cd, utf8);
+ tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, FALSE, cd, utf);
break;
- /* At least one single char sets the bit and stops */
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_POSUPTOI:
+ tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, TRUE, cd, utf);
+ break;
- case OP_EXACT: /* Fall through */
- tcode += 2;
+ /* At least one single char sets the bit and stops */
+ case OP_EXACT:
+ tcode += IMM2_SIZE;
+ /* Fall through */
case OP_CHAR:
- case OP_CHARNC:
case OP_PLUS:
case OP_MINPLUS:
case OP_POSPLUS:
- (void)set_table_bit(start_bits, tcode + 1, caseless, cd, utf8);
+ (void)set_table_bit(start_bits, tcode + 1, FALSE, cd, utf);
+ try_next = FALSE;
+ break;
+
+ case OP_EXACTI:
+ tcode += IMM2_SIZE;
+ /* Fall through */
+ case OP_CHARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ (void)set_table_bit(start_bits, tcode + 1, TRUE, cd, utf);
try_next = FALSE;
break;
@@ -751,14 +988,28 @@
case OP_HSPACE:
SET_BIT(0x09);
SET_BIT(0x20);
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
+#ifdef COMPILE_PCRE8
SET_BIT(0xC2); /* For U+00A0 */
SET_BIT(0xE1); /* For U+1680, U+180E */
SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
SET_BIT(0xE3); /* For U+3000 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xA0);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ else
+#endif /* SUPPORT_UTF */
+ {
+ SET_BIT(0xA0);
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
}
- else SET_BIT(0xA0);
try_next = FALSE;
break;
@@ -768,12 +1019,26 @@
SET_BIT(0x0B);
SET_BIT(0x0C);
SET_BIT(0x0D);
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
+#ifdef COMPILE_PCRE8
SET_BIT(0xC2); /* For U+0085 */
SET_BIT(0xE2); /* For U+2028, U+2029 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0x85);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ else
+#endif /* SUPPORT_UTF */
+ {
+ SET_BIT(0x85);
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
}
- else SET_BIT(0x85);
try_next = FALSE;
break;
@@ -831,7 +1096,7 @@
break;
case OP_TYPEEXACT:
- tcode += 3;
+ tcode += 1 + IMM2_SIZE;
break;
/* Zero or more repeats of character types set the bits and then
@@ -840,7 +1105,7 @@
case OP_TYPEUPTO:
case OP_TYPEMINUPTO:
case OP_TYPEPOSUPTO:
- tcode += 2; /* Fall through */
+ tcode += IMM2_SIZE; /* Fall through */
case OP_TYPESTAR:
case OP_TYPEMINSTAR:
@@ -858,14 +1123,23 @@
case OP_HSPACE:
SET_BIT(0x09);
SET_BIT(0x20);
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
+#ifdef COMPILE_PCRE8
SET_BIT(0xC2); /* For U+00A0 */
SET_BIT(0xE1); /* For U+1680, U+180E */
SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
SET_BIT(0xE3); /* For U+3000 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xA0);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
}
- else SET_BIT(0xA0);
+ else
+#endif /* SUPPORT_UTF */
+ SET_BIT(0xA0);
break;
case OP_ANYNL:
@@ -874,12 +1148,21 @@
SET_BIT(0x0B);
SET_BIT(0x0C);
SET_BIT(0x0D);
- if (utf8)
+#ifdef SUPPORT_UTF
+ if (utf)
{
+#ifdef COMPILE_PCRE8
SET_BIT(0xC2); /* For U+0085 */
SET_BIT(0xE2); /* For U+2028, U+2029 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0x85);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
}
- else SET_BIT(0x85);
+ else
+#endif /* SUPPORT_UTF */
+ SET_BIT(0x85);
break;
case OP_NOT_DIGIT:
@@ -926,18 +1209,23 @@
character with a value > 255. */
case OP_NCLASS:
-#ifdef SUPPORT_UTF8
- if (utf8)
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (utf)
{
start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */
memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
}
#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
/* Fall through */
case OP_CLASS:
{
+ pcre_uint8 *map;
tcode++;
+ map = (pcre_uint8 *)tcode;
/* In UTF-8 mode, the bits in a bit map correspond to character
values, not to byte values. However, the bit map we are constructing is
@@ -945,13 +1233,13 @@
value is > 127. In fact, there are only two possible starting bytes for
characters in the range 128 - 255. */
-#ifdef SUPPORT_UTF8
- if (utf8)
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (utf)
{
- for (c = 0; c < 16; c++) start_bits[c] |= tcode[c];
+ for (c = 0; c < 16; c++) start_bits[c] |= map[c];
for (c = 128; c < 256; c++)
{
- if ((tcode[c/8] && (1 << (c&7))) != 0)
+ if ((map[c/8] && (1 << (c&7))) != 0)
{
int d = (c >> 6) | 0xc0; /* Set bit for this starter */
start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */
@@ -959,18 +1247,17 @@
}
}
}
-
- /* In non-UTF-8 mode, the two bit maps are completely compatible. */
-
else
#endif
{
- for (c = 0; c < 32; c++) start_bits[c] |= tcode[c];
+ /* In non-UTF-8 mode, the two bit maps are completely compatible. */
+ for (c = 0; c < 32; c++) start_bits[c] |= map[c];
}
- /* Advance past the bit map, and act on what follows */
+ /* Advance past the bit map, and act on what follows. For a zero
+ minimum repeat, continue; otherwise stop processing. */
- tcode += 32;
+ tcode += 32 / sizeof(pcre_uchar);
switch (*tcode)
{
case OP_CRSTAR:
@@ -982,7 +1269,7 @@
case OP_CRRANGE:
case OP_CRMINRANGE:
- if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5;
+ if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;
else try_next = FALSE;
break;
@@ -1004,12 +1291,14 @@
+
+
/*************************************************
* Study a compiled expression *
*************************************************/
/* This function is handed a compiled expression that it must study to produce
-information that will speed up the matching. It returns a pcre_extra block
+information that will speed up the matching. It returns a pcre[16]_extra block
which then gets handed back to pcre_exec().
Arguments:
@@ -1018,23 +1307,28 @@
errorptr points to where to place error messages;
set NULL unless error
-Returns: pointer to a pcre_extra block, with study_data filled in and the
- appropriate flags set;
+Returns: pointer to a pcre[16]_extra block, with study_data filled in and
+ the appropriate flags set;
NULL on error or if no optimization possible
*/
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION
pcre_study(const pcre *external_re, int options, const char **errorptr)
+#else
+PCRE_EXP_DEFN pcre16_extra * PCRE_CALL_CONVENTION
+pcre16_study(const pcre16 *external_re, int options, const char **errorptr)
+#endif
{
int min;
BOOL bits_set = FALSE;
-uschar start_bits[32];
-pcre_extra *extra;
+pcre_uint8 start_bits[32];
+PUBL(extra) *extra = NULL;
pcre_study_data *study;
-const uschar *tables;
-uschar *code;
+const pcre_uint8 *tables;
+pcre_uchar *code;
compile_data compile_block;
-const real_pcre *re = (const real_pcre *)external_re;
+const REAL_PCRE *re = (const REAL_PCRE *)external_re;
*errorptr = NULL;
@@ -1044,13 +1338,23 @@
return NULL;
}
+if ((re->flags & PCRE_MODE) == 0)
+ {
+#ifdef COMPILE_PCRE8
+ *errorptr = "argument is compiled in 16 bit mode";
+#else
+ *errorptr = "argument is compiled in 8 bit mode";
+#endif
+ return NULL;
+ }
+
if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
{
*errorptr = "unknown or incorrect option bit(s) set";
return NULL;
}
-code = (uschar *)re + re->name_table_offset +
+code = (pcre_uchar *)re + re->name_table_offset +
(re->name_count * re->name_entry_size);
/* For an anchored pattern, or an unanchored pattern that has a first char, or
@@ -1060,12 +1364,21 @@
if ((re->options & PCRE_ANCHORED) == 0 &&
(re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) == 0)
{
+ int rc;
+
/* Set the character tables in the block that is passed around */
tables = re->tables;
+
+#ifdef COMPILE_PCRE8
if (tables == NULL)
(void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
(void *)(&tables));
+#else
+ if (tables == NULL)
+ (void)pcre16_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
+ (void *)(&tables));
+#endif
compile_block.lcc = tables + lcc_offset;
compile_block.fcc = tables + fcc_offset;
@@ -1074,56 +1387,148 @@
/* See if we can find a fixed set of initial characters for the pattern. */
- memset(start_bits, 0, 32 * sizeof(uschar));
- bits_set = set_start_bits(code, start_bits,
- (re->options & PCRE_CASELESS) != 0, (re->options & PCRE_UTF8) != 0,
- &compile_block) == SSB_DONE;
+ memset(start_bits, 0, 32 * sizeof(pcre_uint8));
+ rc = set_start_bits(code, start_bits, (re->options & PCRE_UTF8) != 0,
+ &compile_block);
+ bits_set = rc == SSB_DONE;
+ if (rc == SSB_UNKNOWN)
+ {
+ *errorptr = "internal error: opcode not recognized";
+ return NULL;
+ }
}
/* Find the minimum length of subject string. */
-min = find_minlength(code, code, re->options);
+switch(min = find_minlength(code, code, re->options, 0))
+ {
+ case -2: *errorptr = "internal error: missing capturing bracket"; return NULL;
+ case -3: *errorptr = "internal error: opcode not recognized"; return NULL;
+ default: break;
+ }
-/* Return NULL if no optimization is possible. */
+/* If a set of starting bytes has been identified, or if the minimum length is
+greater than zero, or if JIT optimization has been requested, get a
+pcre[16]_extra block and a pcre_study_data block. The study data is put in the
+latter, which is pointed to by the former, which may also get additional data
+set later by the calling program. At the moment, the size of pcre_study_data
+is fixed. We nevertheless save it in a field for returning via the
+pcre_fullinfo() function so that if it becomes variable in the future,
+we don't have to change that code. */
+
+if (bits_set || min > 0
+#ifdef SUPPORT_JIT
+ || (options & (PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
+ | PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE)) != 0
+#endif
+ )
+ {
+ extra = (PUBL(extra) *)(PUBL(malloc))
+ (sizeof(PUBL(extra)) + sizeof(pcre_study_data));
+ if (extra == NULL)
+ {
+ *errorptr = "failed to get memory";
+ return NULL;
+ }
-if (!bits_set && min < 0) return NULL;
+ study = (pcre_study_data *)((char *)extra + sizeof(PUBL(extra)));
+ extra->flags = PCRE_EXTRA_STUDY_DATA;
+ extra->study_data = study;
+
+ study->size = sizeof(pcre_study_data);
+ study->flags = 0;
+
+ /* Set the start bits always, to avoid unset memory errors if the
+ study data is written to a file, but set the flag only if any of the bits
+ are set, to save time looking when none are. */
-/* Get a pcre_extra block and a pcre_study_data block. The study data is put in
-the latter, which is pointed to by the former, which may also get additional
-data set later by the calling program. At the moment, the size of
-pcre_study_data is fixed. We nevertheless save it in a field for returning via
-the pcre_fullinfo() function so that if it becomes variable in the future, we
-don't have to change that code. */
+ if (bits_set)
+ {
+ study->flags |= PCRE_STUDY_MAPPED;
+ memcpy(study->start_bits, start_bits, sizeof(start_bits));
+ }
+ else memset(study->start_bits, 0, 32 * sizeof(pcre_uint8));
-extra = (pcre_extra *)(pcre_malloc)
- (sizeof(pcre_extra) + sizeof(pcre_study_data));
+#ifdef PCRE_DEBUG
+ if (bits_set)
+ {
+ pcre_uint8 *ptr = start_bits;
+ int i;
-if (extra == NULL)
- {
- *errorptr = "failed to get memory";
- return NULL;
- }
+ printf("Start bits:\n");
+ for (i = 0; i < 32; i++)
+ printf("%3d: %02x%s", i * 8, *ptr++, ((i + 1) & 0x7) != 0? " " : "\n");
+ }
+#endif
-study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra));
-extra->flags = PCRE_EXTRA_STUDY_DATA;
-extra->study_data = study;
+ /* Always set the minlength value in the block, because the JIT compiler
+ makes use of it. However, don't set the bit unless the length is greater than
+ zero - the interpretive pcre_exec() and pcre_dfa_exec() needn't waste time
+ checking the zero case. */
-study->size = sizeof(pcre_study_data);
-study->flags = 0;
+ if (min > 0)
+ {
+ study->flags |= PCRE_STUDY_MINLEN;
+ study->minlength = min;
+ }
+ else study->minlength = 0;
-if (bits_set)
- {
- study->flags |= PCRE_STUDY_MAPPED;
- memcpy(study->start_bits, start_bits, sizeof(start_bits));
- }
+ /* If JIT support was compiled and requested, attempt the JIT compilation.
+ If no starting bytes were found, and the minimum length is zero, and JIT
+ compilation fails, abandon the extra block and return NULL. */
+
+#ifdef SUPPORT_JIT
+ extra->executable_jit = NULL;
+ if ((options & PCRE_STUDY_JIT_COMPILE) != 0)
+ PRIV(jit_compile)(re, extra, JIT_COMPILE);
+ if ((options & PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE) != 0)
+ PRIV(jit_compile)(re, extra, JIT_PARTIAL_SOFT_COMPILE);
+ if ((options & PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) != 0)
+ PRIV(jit_compile)(re, extra, JIT_PARTIAL_HARD_COMPILE);
-if (min >= 0)
- {
- study->flags |= PCRE_STUDY_MINLEN;
- study->minlength = min;
+ if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0)
+ {
+#ifdef COMPILE_PCRE8
+ pcre_free_study(extra);
+#endif
+#ifdef COMPILE_PCRE16
+ pcre16_free_study(extra);
+#endif
+ extra = NULL;
+ }
+#endif
}
return extra;
}
+
+/*************************************************
+* Free the study data *
+*************************************************/
+
+/* This function frees the memory that was obtained by pcre_study().
+
+Argument: a pointer to the pcre[16]_extra block
+Returns: nothing
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN void
+pcre_free_study(pcre_extra *extra)
+#else
+PCRE_EXP_DEFN void
+pcre16_free_study(pcre16_extra *extra)
+#endif
+{
+if (extra == NULL)
+ return;
+#ifdef SUPPORT_JIT
+if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra->executable_jit != NULL)
+ PRIV(jit_free)(extra->executable_jit);
+#endif
+PUBL(free)(extra);
+}
+
/* End of pcre_study.c */
diff -Nru pcre3-8.12/pcre_tables.c pcre3-8.31/pcre_tables.c
--- pcre3-8.12/pcre_tables.c 2010-05-04 16:06:12.000000000 +0000
+++ pcre3-8.31/pcre_tables.c 2012-06-02 10:55:16.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2009 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,7 @@
-----------------------------------------------------------------------------
*/
+#ifndef PCRE_INCLUDED
/* This module contains some fixed tables that are used by more than one of the
PCRE code modules. The tables are also #included by the pcretest program, which
@@ -50,11 +51,12 @@
#include "pcre_internal.h"
+#endif /* PCRE_INCLUDED */
/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
the definition is next to the definition of the opcodes in pcre_internal.h. */
-const uschar _pcre_OP_lengths[] = { OP_LENGTHS };
+const pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS };
@@ -65,31 +67,38 @@
/* These are the breakpoints for different numbers of bytes in a UTF-8
character. */
-#ifdef SUPPORT_UTF8
+#if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \
+ || (defined PCRE_INCLUDED && defined SUPPORT_PCRE16)
-const int _pcre_utf8_table1[] =
+/* These tables are also required by pcretest in 16 bit mode. */
+
+const int PRIV(utf8_table1)[] =
{ 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
-const int _pcre_utf8_table1_size = sizeof(_pcre_utf8_table1)/sizeof(int);
+const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int);
/* These are the indicator bits and the mask for the data bits to set in the
first byte of a character, indexed by the number of additional bytes. */
-const int _pcre_utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
-const int _pcre_utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
+const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
+const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
/* Table of the number of extra bytes, indexed by the first byte masked with
0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
-const uschar _pcre_utf8_table4[] = {
+const pcre_uint8 PRIV(utf8_table4)[] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
+#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE16)*/
+
+#ifdef SUPPORT_UTF
+
/* Table to translate from particular type value to the general value. */
-const int _pcre_ucp_gentype[] = {
+const int PRIV(ucp_gentype)[] = {
ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */
ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */
ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */
@@ -100,6 +109,21 @@
ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */
};
+#ifdef SUPPORT_JIT
+/* This table reverses PRIV(ucp_gentype). We can save the cost
+of a memory load. */
+
+const int PRIV(ucp_typerange)[] = {
+ ucp_Cc, ucp_Cs,
+ ucp_Ll, ucp_Lu,
+ ucp_Mc, ucp_Mn,
+ ucp_Nd, ucp_No,
+ ucp_Pc, ucp_Ps,
+ ucp_Sc, ucp_So,
+ ucp_Zl, ucp_Zs,
+};
+#endif /* SUPPORT_JIT */
+
/* The pcre_utt[] table below translates Unicode property names into type and
code values. It is searched by binary chop, so must be in collating sequence of
name. Originally, the table contained pointers to the name strings in the first
@@ -110,7 +134,7 @@
data are unlikely.
July 2008: There is now a script called maint/GenerateUtt.py that can be used
-to generate this data instead of maintaining it entirely by hand.
+to generate this data automatically instead of maintaining it by hand.
The script was updated in March 2009 to generate a new EBCDIC-compliant
version. Like all other character and string literals that are compared against
@@ -123,8 +147,10 @@
#define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0"
#define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0"
#define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0"
+#define STRING_Batak0 STR_B STR_a STR_t STR_a STR_k "\0"
#define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0"
#define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0"
+#define STRING_Brahmi0 STR_B STR_r STR_a STR_h STR_m STR_i "\0"
#define STRING_Braille0 STR_B STR_r STR_a STR_i STR_l STR_l STR_e "\0"
#define STRING_Buginese0 STR_B STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0"
#define STRING_Buhid0 STR_B STR_u STR_h STR_i STR_d "\0"
@@ -133,6 +159,7 @@
#define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0"
#define STRING_Cc0 STR_C STR_c "\0"
#define STRING_Cf0 STR_C STR_f "\0"
+#define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0"
#define STRING_Cham0 STR_C STR_h STR_a STR_m "\0"
#define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0"
#define STRING_Cn0 STR_C STR_n "\0"
@@ -186,9 +213,13 @@
#define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0"
#define STRING_M0 STR_M "\0"
#define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0"
+#define STRING_Mandaic0 STR_M STR_a STR_n STR_d STR_a STR_i STR_c "\0"
#define STRING_Mc0 STR_M STR_c "\0"
#define STRING_Me0 STR_M STR_e "\0"
#define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0"
+#define STRING_Meroitic_Cursive0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_C STR_u STR_r STR_s STR_i STR_v STR_e "\0"
+#define STRING_Meroitic_Hieroglyphs0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
+#define STRING_Miao0 STR_M STR_i STR_a STR_o "\0"
#define STRING_Mn0 STR_M STR_n "\0"
#define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0"
#define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0"
@@ -222,11 +253,13 @@
#define STRING_Samaritan0 STR_S STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0"
#define STRING_Saurashtra0 STR_S STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0"
#define STRING_Sc0 STR_S STR_c "\0"
+#define STRING_Sharada0 STR_S STR_h STR_a STR_r STR_a STR_d STR_a "\0"
#define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0"
#define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0"
#define STRING_Sk0 STR_S STR_k "\0"
#define STRING_Sm0 STR_S STR_m "\0"
#define STRING_So0 STR_S STR_o "\0"
+#define STRING_Sora_Sompeng0 STR_S STR_o STR_r STR_a STR_UNDERSCORE STR_S STR_o STR_m STR_p STR_e STR_n STR_g "\0"
#define STRING_Sundanese0 STR_S STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0"
#define STRING_Syloti_Nagri0 STR_S STR_y STR_l STR_o STR_t STR_i STR_UNDERSCORE STR_N STR_a STR_g STR_r STR_i "\0"
#define STRING_Syriac0 STR_S STR_y STR_r STR_i STR_a STR_c "\0"
@@ -235,6 +268,7 @@
#define STRING_Tai_Le0 STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_e "\0"
#define STRING_Tai_Tham0 STR_T STR_a STR_i STR_UNDERSCORE STR_T STR_h STR_a STR_m "\0"
#define STRING_Tai_Viet0 STR_T STR_a STR_i STR_UNDERSCORE STR_V STR_i STR_e STR_t "\0"
+#define STRING_Takri0 STR_T STR_a STR_k STR_r STR_i "\0"
#define STRING_Tamil0 STR_T STR_a STR_m STR_i STR_l "\0"
#define STRING_Telugu0 STR_T STR_e STR_l STR_u STR_g STR_u "\0"
#define STRING_Thaana0 STR_T STR_h STR_a STR_a STR_n STR_a "\0"
@@ -253,15 +287,17 @@
#define STRING_Zp0 STR_Z STR_p "\0"
#define STRING_Zs0 STR_Z STR_s "\0"
-const char _pcre_utt_names[] =
+const char PRIV(utt_names)[] =
STRING_Any0
STRING_Arabic0
STRING_Armenian0
STRING_Avestan0
STRING_Balinese0
STRING_Bamum0
+ STRING_Batak0
STRING_Bengali0
STRING_Bopomofo0
+ STRING_Brahmi0
STRING_Braille0
STRING_Buginese0
STRING_Buhid0
@@ -270,6 +306,7 @@
STRING_Carian0
STRING_Cc0
STRING_Cf0
+ STRING_Chakma0
STRING_Cham0
STRING_Cherokee0
STRING_Cn0
@@ -323,9 +360,13 @@
STRING_Lydian0
STRING_M0
STRING_Malayalam0
+ STRING_Mandaic0
STRING_Mc0
STRING_Me0
STRING_Meetei_Mayek0
+ STRING_Meroitic_Cursive0
+ STRING_Meroitic_Hieroglyphs0
+ STRING_Miao0
STRING_Mn0
STRING_Mongolian0
STRING_Myanmar0
@@ -359,11 +400,13 @@
STRING_Samaritan0
STRING_Saurashtra0
STRING_Sc0
+ STRING_Sharada0
STRING_Shavian0
STRING_Sinhala0
STRING_Sk0
STRING_Sm0
STRING_So0
+ STRING_Sora_Sompeng0
STRING_Sundanese0
STRING_Syloti_Nagri0
STRING_Syriac0
@@ -372,6 +415,7 @@
STRING_Tai_Le0
STRING_Tai_Tham0
STRING_Tai_Viet0
+ STRING_Takri0
STRING_Tamil0
STRING_Telugu0
STRING_Thaana0
@@ -390,146 +434,156 @@
STRING_Zp0
STRING_Zs0;
-const ucp_type_table _pcre_utt[] = {
+const ucp_type_table PRIV(utt)[] = {
{ 0, PT_ANY, 0 },
{ 4, PT_SC, ucp_Arabic },
{ 11, PT_SC, ucp_Armenian },
{ 20, PT_SC, ucp_Avestan },
{ 28, PT_SC, ucp_Balinese },
{ 37, PT_SC, ucp_Bamum },
- { 43, PT_SC, ucp_Bengali },
- { 51, PT_SC, ucp_Bopomofo },
- { 60, PT_SC, ucp_Braille },
- { 68, PT_SC, ucp_Buginese },
- { 77, PT_SC, ucp_Buhid },
- { 83, PT_GC, ucp_C },
- { 85, PT_SC, ucp_Canadian_Aboriginal },
- { 105, PT_SC, ucp_Carian },
- { 112, PT_PC, ucp_Cc },
- { 115, PT_PC, ucp_Cf },
- { 118, PT_SC, ucp_Cham },
- { 123, PT_SC, ucp_Cherokee },
- { 132, PT_PC, ucp_Cn },
- { 135, PT_PC, ucp_Co },
- { 138, PT_SC, ucp_Common },
- { 145, PT_SC, ucp_Coptic },
- { 152, PT_PC, ucp_Cs },
- { 155, PT_SC, ucp_Cuneiform },
- { 165, PT_SC, ucp_Cypriot },
- { 173, PT_SC, ucp_Cyrillic },
- { 182, PT_SC, ucp_Deseret },
- { 190, PT_SC, ucp_Devanagari },
- { 201, PT_SC, ucp_Egyptian_Hieroglyphs },
- { 222, PT_SC, ucp_Ethiopic },
- { 231, PT_SC, ucp_Georgian },
- { 240, PT_SC, ucp_Glagolitic },
- { 251, PT_SC, ucp_Gothic },
- { 258, PT_SC, ucp_Greek },
- { 264, PT_SC, ucp_Gujarati },
- { 273, PT_SC, ucp_Gurmukhi },
- { 282, PT_SC, ucp_Han },
- { 286, PT_SC, ucp_Hangul },
- { 293, PT_SC, ucp_Hanunoo },
- { 301, PT_SC, ucp_Hebrew },
- { 308, PT_SC, ucp_Hiragana },
- { 317, PT_SC, ucp_Imperial_Aramaic },
- { 334, PT_SC, ucp_Inherited },
- { 344, PT_SC, ucp_Inscriptional_Pahlavi },
- { 366, PT_SC, ucp_Inscriptional_Parthian },
- { 389, PT_SC, ucp_Javanese },
- { 398, PT_SC, ucp_Kaithi },
- { 405, PT_SC, ucp_Kannada },
- { 413, PT_SC, ucp_Katakana },
- { 422, PT_SC, ucp_Kayah_Li },
- { 431, PT_SC, ucp_Kharoshthi },
- { 442, PT_SC, ucp_Khmer },
- { 448, PT_GC, ucp_L },
- { 450, PT_LAMP, 0 },
- { 453, PT_SC, ucp_Lao },
- { 457, PT_SC, ucp_Latin },
- { 463, PT_SC, ucp_Lepcha },
- { 470, PT_SC, ucp_Limbu },
- { 476, PT_SC, ucp_Linear_B },
- { 485, PT_SC, ucp_Lisu },
- { 490, PT_PC, ucp_Ll },
- { 493, PT_PC, ucp_Lm },
- { 496, PT_PC, ucp_Lo },
- { 499, PT_PC, ucp_Lt },
- { 502, PT_PC, ucp_Lu },
- { 505, PT_SC, ucp_Lycian },
- { 512, PT_SC, ucp_Lydian },
- { 519, PT_GC, ucp_M },
- { 521, PT_SC, ucp_Malayalam },
- { 531, PT_PC, ucp_Mc },
- { 534, PT_PC, ucp_Me },
- { 537, PT_SC, ucp_Meetei_Mayek },
- { 550, PT_PC, ucp_Mn },
- { 553, PT_SC, ucp_Mongolian },
- { 563, PT_SC, ucp_Myanmar },
- { 571, PT_GC, ucp_N },
- { 573, PT_PC, ucp_Nd },
- { 576, PT_SC, ucp_New_Tai_Lue },
- { 588, PT_SC, ucp_Nko },
- { 592, PT_PC, ucp_Nl },
- { 595, PT_PC, ucp_No },
- { 598, PT_SC, ucp_Ogham },
- { 604, PT_SC, ucp_Ol_Chiki },
- { 613, PT_SC, ucp_Old_Italic },
- { 624, PT_SC, ucp_Old_Persian },
- { 636, PT_SC, ucp_Old_South_Arabian },
- { 654, PT_SC, ucp_Old_Turkic },
- { 665, PT_SC, ucp_Oriya },
- { 671, PT_SC, ucp_Osmanya },
- { 679, PT_GC, ucp_P },
- { 681, PT_PC, ucp_Pc },
- { 684, PT_PC, ucp_Pd },
- { 687, PT_PC, ucp_Pe },
- { 690, PT_PC, ucp_Pf },
- { 693, PT_SC, ucp_Phags_Pa },
- { 702, PT_SC, ucp_Phoenician },
- { 713, PT_PC, ucp_Pi },
- { 716, PT_PC, ucp_Po },
- { 719, PT_PC, ucp_Ps },
- { 722, PT_SC, ucp_Rejang },
- { 729, PT_SC, ucp_Runic },
- { 735, PT_GC, ucp_S },
- { 737, PT_SC, ucp_Samaritan },
- { 747, PT_SC, ucp_Saurashtra },
- { 758, PT_PC, ucp_Sc },
- { 761, PT_SC, ucp_Shavian },
- { 769, PT_SC, ucp_Sinhala },
- { 777, PT_PC, ucp_Sk },
- { 780, PT_PC, ucp_Sm },
- { 783, PT_PC, ucp_So },
- { 786, PT_SC, ucp_Sundanese },
- { 796, PT_SC, ucp_Syloti_Nagri },
- { 809, PT_SC, ucp_Syriac },
- { 816, PT_SC, ucp_Tagalog },
- { 824, PT_SC, ucp_Tagbanwa },
- { 833, PT_SC, ucp_Tai_Le },
- { 840, PT_SC, ucp_Tai_Tham },
- { 849, PT_SC, ucp_Tai_Viet },
- { 858, PT_SC, ucp_Tamil },
- { 864, PT_SC, ucp_Telugu },
- { 871, PT_SC, ucp_Thaana },
- { 878, PT_SC, ucp_Thai },
- { 883, PT_SC, ucp_Tibetan },
- { 891, PT_SC, ucp_Tifinagh },
- { 900, PT_SC, ucp_Ugaritic },
- { 909, PT_SC, ucp_Vai },
- { 913, PT_ALNUM, 0 },
- { 917, PT_PXSPACE, 0 },
- { 921, PT_SPACE, 0 },
- { 925, PT_WORD, 0 },
- { 929, PT_SC, ucp_Yi },
- { 932, PT_GC, ucp_Z },
- { 934, PT_PC, ucp_Zl },
- { 937, PT_PC, ucp_Zp },
- { 940, PT_PC, ucp_Zs }
+ { 43, PT_SC, ucp_Batak },
+ { 49, PT_SC, ucp_Bengali },
+ { 57, PT_SC, ucp_Bopomofo },
+ { 66, PT_SC, ucp_Brahmi },
+ { 73, PT_SC, ucp_Braille },
+ { 81, PT_SC, ucp_Buginese },
+ { 90, PT_SC, ucp_Buhid },
+ { 96, PT_GC, ucp_C },
+ { 98, PT_SC, ucp_Canadian_Aboriginal },
+ { 118, PT_SC, ucp_Carian },
+ { 125, PT_PC, ucp_Cc },
+ { 128, PT_PC, ucp_Cf },
+ { 131, PT_SC, ucp_Chakma },
+ { 138, PT_SC, ucp_Cham },
+ { 143, PT_SC, ucp_Cherokee },
+ { 152, PT_PC, ucp_Cn },
+ { 155, PT_PC, ucp_Co },
+ { 158, PT_SC, ucp_Common },
+ { 165, PT_SC, ucp_Coptic },
+ { 172, PT_PC, ucp_Cs },
+ { 175, PT_SC, ucp_Cuneiform },
+ { 185, PT_SC, ucp_Cypriot },
+ { 193, PT_SC, ucp_Cyrillic },
+ { 202, PT_SC, ucp_Deseret },
+ { 210, PT_SC, ucp_Devanagari },
+ { 221, PT_SC, ucp_Egyptian_Hieroglyphs },
+ { 242, PT_SC, ucp_Ethiopic },
+ { 251, PT_SC, ucp_Georgian },
+ { 260, PT_SC, ucp_Glagolitic },
+ { 271, PT_SC, ucp_Gothic },
+ { 278, PT_SC, ucp_Greek },
+ { 284, PT_SC, ucp_Gujarati },
+ { 293, PT_SC, ucp_Gurmukhi },
+ { 302, PT_SC, ucp_Han },
+ { 306, PT_SC, ucp_Hangul },
+ { 313, PT_SC, ucp_Hanunoo },
+ { 321, PT_SC, ucp_Hebrew },
+ { 328, PT_SC, ucp_Hiragana },
+ { 337, PT_SC, ucp_Imperial_Aramaic },
+ { 354, PT_SC, ucp_Inherited },
+ { 364, PT_SC, ucp_Inscriptional_Pahlavi },
+ { 386, PT_SC, ucp_Inscriptional_Parthian },
+ { 409, PT_SC, ucp_Javanese },
+ { 418, PT_SC, ucp_Kaithi },
+ { 425, PT_SC, ucp_Kannada },
+ { 433, PT_SC, ucp_Katakana },
+ { 442, PT_SC, ucp_Kayah_Li },
+ { 451, PT_SC, ucp_Kharoshthi },
+ { 462, PT_SC, ucp_Khmer },
+ { 468, PT_GC, ucp_L },
+ { 470, PT_LAMP, 0 },
+ { 473, PT_SC, ucp_Lao },
+ { 477, PT_SC, ucp_Latin },
+ { 483, PT_SC, ucp_Lepcha },
+ { 490, PT_SC, ucp_Limbu },
+ { 496, PT_SC, ucp_Linear_B },
+ { 505, PT_SC, ucp_Lisu },
+ { 510, PT_PC, ucp_Ll },
+ { 513, PT_PC, ucp_Lm },
+ { 516, PT_PC, ucp_Lo },
+ { 519, PT_PC, ucp_Lt },
+ { 522, PT_PC, ucp_Lu },
+ { 525, PT_SC, ucp_Lycian },
+ { 532, PT_SC, ucp_Lydian },
+ { 539, PT_GC, ucp_M },
+ { 541, PT_SC, ucp_Malayalam },
+ { 551, PT_SC, ucp_Mandaic },
+ { 559, PT_PC, ucp_Mc },
+ { 562, PT_PC, ucp_Me },
+ { 565, PT_SC, ucp_Meetei_Mayek },
+ { 578, PT_SC, ucp_Meroitic_Cursive },
+ { 595, PT_SC, ucp_Meroitic_Hieroglyphs },
+ { 616, PT_SC, ucp_Miao },
+ { 621, PT_PC, ucp_Mn },
+ { 624, PT_SC, ucp_Mongolian },
+ { 634, PT_SC, ucp_Myanmar },
+ { 642, PT_GC, ucp_N },
+ { 644, PT_PC, ucp_Nd },
+ { 647, PT_SC, ucp_New_Tai_Lue },
+ { 659, PT_SC, ucp_Nko },
+ { 663, PT_PC, ucp_Nl },
+ { 666, PT_PC, ucp_No },
+ { 669, PT_SC, ucp_Ogham },
+ { 675, PT_SC, ucp_Ol_Chiki },
+ { 684, PT_SC, ucp_Old_Italic },
+ { 695, PT_SC, ucp_Old_Persian },
+ { 707, PT_SC, ucp_Old_South_Arabian },
+ { 725, PT_SC, ucp_Old_Turkic },
+ { 736, PT_SC, ucp_Oriya },
+ { 742, PT_SC, ucp_Osmanya },
+ { 750, PT_GC, ucp_P },
+ { 752, PT_PC, ucp_Pc },
+ { 755, PT_PC, ucp_Pd },
+ { 758, PT_PC, ucp_Pe },
+ { 761, PT_PC, ucp_Pf },
+ { 764, PT_SC, ucp_Phags_Pa },
+ { 773, PT_SC, ucp_Phoenician },
+ { 784, PT_PC, ucp_Pi },
+ { 787, PT_PC, ucp_Po },
+ { 790, PT_PC, ucp_Ps },
+ { 793, PT_SC, ucp_Rejang },
+ { 800, PT_SC, ucp_Runic },
+ { 806, PT_GC, ucp_S },
+ { 808, PT_SC, ucp_Samaritan },
+ { 818, PT_SC, ucp_Saurashtra },
+ { 829, PT_PC, ucp_Sc },
+ { 832, PT_SC, ucp_Sharada },
+ { 840, PT_SC, ucp_Shavian },
+ { 848, PT_SC, ucp_Sinhala },
+ { 856, PT_PC, ucp_Sk },
+ { 859, PT_PC, ucp_Sm },
+ { 862, PT_PC, ucp_So },
+ { 865, PT_SC, ucp_Sora_Sompeng },
+ { 878, PT_SC, ucp_Sundanese },
+ { 888, PT_SC, ucp_Syloti_Nagri },
+ { 901, PT_SC, ucp_Syriac },
+ { 908, PT_SC, ucp_Tagalog },
+ { 916, PT_SC, ucp_Tagbanwa },
+ { 925, PT_SC, ucp_Tai_Le },
+ { 932, PT_SC, ucp_Tai_Tham },
+ { 941, PT_SC, ucp_Tai_Viet },
+ { 950, PT_SC, ucp_Takri },
+ { 956, PT_SC, ucp_Tamil },
+ { 962, PT_SC, ucp_Telugu },
+ { 969, PT_SC, ucp_Thaana },
+ { 976, PT_SC, ucp_Thai },
+ { 981, PT_SC, ucp_Tibetan },
+ { 989, PT_SC, ucp_Tifinagh },
+ { 998, PT_SC, ucp_Ugaritic },
+ { 1007, PT_SC, ucp_Vai },
+ { 1011, PT_ALNUM, 0 },
+ { 1015, PT_PXSPACE, 0 },
+ { 1019, PT_SPACE, 0 },
+ { 1023, PT_WORD, 0 },
+ { 1027, PT_SC, ucp_Yi },
+ { 1030, PT_GC, ucp_Z },
+ { 1032, PT_PC, ucp_Zl },
+ { 1035, PT_PC, ucp_Zp },
+ { 1038, PT_PC, ucp_Zs }
};
-const int _pcre_utt_size = sizeof(_pcre_utt)/sizeof(ucp_type_table);
+const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
-#endif /* SUPPORT_UTF8 */
+#endif /* SUPPORT_UTF */
/* End of pcre_tables.c */
diff -Nru pcre3-8.12/pcre_try_flipped.c pcre3-8.31/pcre_try_flipped.c
--- pcre3-8.12/pcre_try_flipped.c 2009-10-05 10:40:30.000000000 +0000
+++ pcre3-8.31/pcre_try_flipped.c 1970-01-01 00:00:00.000000000 +0000
@@ -1,139 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2009 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains an internal function that tests a compiled pattern to
-see if it was compiled with the opposite endianness. If so, it uses an
-auxiliary local function to flip the appropriate bytes. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Flip bytes in an integer *
-*************************************************/
-
-/* This function is called when the magic number in a regex doesn't match, in
-order to flip its bytes to see if we are dealing with a pattern that was
-compiled on a host of different endianness. If so, this function is used to
-flip other byte values.
-
-Arguments:
- value the number to flip
- n the number of bytes to flip (assumed to be 2 or 4)
-
-Returns: the flipped value
-*/
-
-static unsigned long int
-byteflip(unsigned long int value, int n)
-{
-if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
-return ((value & 0x000000ff) << 24) |
- ((value & 0x0000ff00) << 8) |
- ((value & 0x00ff0000) >> 8) |
- ((value & 0xff000000) >> 24);
-}
-
-
-
-/*************************************************
-* Test for a byte-flipped compiled regex *
-*************************************************/
-
-/* This function is called from pcre_exec(), pcre_dfa_exec(), and also from
-pcre_fullinfo(). Its job is to test whether the regex is byte-flipped - that
-is, it was compiled on a system of opposite endianness. The function is called
-only when the native MAGIC_NUMBER test fails. If the regex is indeed flipped,
-we flip all the relevant values into a different data block, and return it.
-
-Arguments:
- re points to the regex
- study points to study data, or NULL
- internal_re points to a new regex block
- internal_study points to a new study block
-
-Returns: the new block if is is indeed a byte-flipped regex
- NULL if it is not
-*/
-
-real_pcre *
-_pcre_try_flipped(const real_pcre *re, real_pcre *internal_re,
- const pcre_study_data *study, pcre_study_data *internal_study)
-{
-if (byteflip(re->magic_number, sizeof(re->magic_number)) != MAGIC_NUMBER)
- return NULL;
-
-*internal_re = *re; /* To copy other fields */
-internal_re->size = byteflip(re->size, sizeof(re->size));
-internal_re->options = byteflip(re->options, sizeof(re->options));
-internal_re->flags = (pcre_uint16)byteflip(re->flags, sizeof(re->flags));
-internal_re->top_bracket =
- (pcre_uint16)byteflip(re->top_bracket, sizeof(re->top_bracket));
-internal_re->top_backref =
- (pcre_uint16)byteflip(re->top_backref, sizeof(re->top_backref));
-internal_re->first_byte =
- (pcre_uint16)byteflip(re->first_byte, sizeof(re->first_byte));
-internal_re->req_byte =
- (pcre_uint16)byteflip(re->req_byte, sizeof(re->req_byte));
-internal_re->name_table_offset =
- (pcre_uint16)byteflip(re->name_table_offset, sizeof(re->name_table_offset));
-internal_re->name_entry_size =
- (pcre_uint16)byteflip(re->name_entry_size, sizeof(re->name_entry_size));
-internal_re->name_count =
- (pcre_uint16)byteflip(re->name_count, sizeof(re->name_count));
-
-if (study != NULL)
- {
- *internal_study = *study; /* To copy other fields */
- internal_study->size = byteflip(study->size, sizeof(study->size));
- internal_study->flags = byteflip(study->flags, sizeof(study->flags));
- internal_study->minlength = byteflip(study->minlength,
- sizeof(study->minlength));
- }
-
-return internal_re;
-}
-
-/* End of pcre_tryflipped.c */
diff -Nru pcre3-8.12/pcre_ucd.c pcre3-8.31/pcre_ucd.c
--- pcre3-8.12/pcre_ucd.c 2010-03-01 16:11:00.000000000 +0000
+++ pcre3-8.31/pcre_ucd.c 2012-02-28 14:31:31.000000000 +0000
@@ -6,7 +6,7 @@
/* Unicode character database. */
/* This file was autogenerated by the MultiStage2.py script. */
-/* Total size: 56880 bytes, block size: 128. */
+/* Total size: 62904 bytes, block size: 128. */
/* The tables herein are needed only when UCP support is built */
/* into PCRE. This module should not be referenced otherwise, so */
@@ -18,21 +18,21 @@
/* Instead, just supply small dummy tables. */
#ifndef SUPPORT_UCP
-const ucd_record _pcre_ucd_records[] = {{0,0,0 }};
-const uschar _pcre_ucd_stage1[] = {0};
-const pcre_uint16 _pcre_ucd_stage2[] = {0};
+const ucd_record PRIV(ucd_records)[] = {{0,0,0 }};
+const pcre_uint8 PRIV(ucd_stage1)[] = {0};
+const pcre_uint16 PRIV(ucd_stage2)[] = {0};
#else
/* When recompiling tables with a new Unicode version,
please check types in the structure definition from pcre_internal.h:
typedef struct {
-uschar property_0;
-uschar property_1;
+pcre_uint8 property_0;
+pcre_uint8 property_1;
pcre_int32 property_2;
} ucd_record; */
-const ucd_record _pcre_ucd_records[] = { /* 4144 bytes, record size 8 */
+const ucd_record PRIV(ucd_records)[] = { /* 4536 bytes, record size 8 */
{ 9, 0, 0, }, /* 0 */
{ 9, 29, 0, }, /* 1 */
{ 9, 21, 0, }, /* 2 */
@@ -47,38 +47,38 @@
{ 9, 16, 0, }, /* 11 */
{ 33, 5, -32, }, /* 12 */
{ 9, 26, 0, }, /* 13 */
- { 33, 5, 0, }, /* 14 */
+ { 33, 7, 0, }, /* 14 */
{ 9, 20, 0, }, /* 15 */
{ 9, 1, 0, }, /* 16 */
{ 9, 15, 0, }, /* 17 */
{ 9, 5, 743, }, /* 18 */
{ 9, 19, 0, }, /* 19 */
- { 33, 5, 121, }, /* 20 */
- { 33, 9, 1, }, /* 21 */
- { 33, 5, -1, }, /* 22 */
- { 33, 9, -199, }, /* 23 */
- { 33, 5, -232, }, /* 24 */
- { 33, 9, -121, }, /* 25 */
- { 33, 5, -300, }, /* 26 */
- { 33, 5, 195, }, /* 27 */
- { 33, 9, 210, }, /* 28 */
- { 33, 9, 206, }, /* 29 */
- { 33, 9, 205, }, /* 30 */
- { 33, 9, 79, }, /* 31 */
- { 33, 9, 202, }, /* 32 */
- { 33, 9, 203, }, /* 33 */
- { 33, 9, 207, }, /* 34 */
- { 33, 5, 97, }, /* 35 */
- { 33, 9, 211, }, /* 36 */
- { 33, 9, 209, }, /* 37 */
- { 33, 5, 163, }, /* 38 */
- { 33, 9, 213, }, /* 39 */
- { 33, 5, 130, }, /* 40 */
- { 33, 9, 214, }, /* 41 */
- { 33, 9, 218, }, /* 42 */
- { 33, 9, 217, }, /* 43 */
- { 33, 9, 219, }, /* 44 */
- { 33, 7, 0, }, /* 45 */
+ { 33, 5, 0, }, /* 20 */
+ { 33, 5, 121, }, /* 21 */
+ { 33, 9, 1, }, /* 22 */
+ { 33, 5, -1, }, /* 23 */
+ { 33, 9, -199, }, /* 24 */
+ { 33, 5, -232, }, /* 25 */
+ { 33, 9, -121, }, /* 26 */
+ { 33, 5, -300, }, /* 27 */
+ { 33, 5, 195, }, /* 28 */
+ { 33, 9, 210, }, /* 29 */
+ { 33, 9, 206, }, /* 30 */
+ { 33, 9, 205, }, /* 31 */
+ { 33, 9, 79, }, /* 32 */
+ { 33, 9, 202, }, /* 33 */
+ { 33, 9, 203, }, /* 34 */
+ { 33, 9, 207, }, /* 35 */
+ { 33, 5, 97, }, /* 36 */
+ { 33, 9, 211, }, /* 37 */
+ { 33, 9, 209, }, /* 38 */
+ { 33, 5, 163, }, /* 39 */
+ { 33, 9, 213, }, /* 40 */
+ { 33, 5, 130, }, /* 41 */
+ { 33, 9, 214, }, /* 42 */
+ { 33, 9, 218, }, /* 43 */
+ { 33, 9, 217, }, /* 44 */
+ { 33, 9, 219, }, /* 45 */
{ 33, 5, 56, }, /* 46 */
{ 33, 9, 2, }, /* 47 */
{ 33, 8, -1, }, /* 48 */
@@ -103,463 +103,512 @@
{ 33, 5, -202, }, /* 67 */
{ 33, 5, -203, }, /* 68 */
{ 33, 5, -207, }, /* 69 */
- { 33, 5, -209, }, /* 70 */
- { 33, 5, -211, }, /* 71 */
- { 33, 5, 10743, }, /* 72 */
- { 33, 5, 10749, }, /* 73 */
- { 33, 5, -213, }, /* 74 */
- { 33, 5, -214, }, /* 75 */
- { 33, 5, 10727, }, /* 76 */
- { 33, 5, -218, }, /* 77 */
- { 33, 5, -69, }, /* 78 */
- { 33, 5, -217, }, /* 79 */
- { 33, 5, -71, }, /* 80 */
- { 33, 5, -219, }, /* 81 */
- { 33, 6, 0, }, /* 82 */
- { 9, 6, 0, }, /* 83 */
- { 27, 12, 0, }, /* 84 */
- { 27, 12, 84, }, /* 85 */
- { 19, 9, 1, }, /* 86 */
- { 19, 5, -1, }, /* 87 */
- { 19, 24, 0, }, /* 88 */
- { 9, 2, 0, }, /* 89 */
- { 19, 6, 0, }, /* 90 */
- { 19, 5, 130, }, /* 91 */
- { 19, 9, 38, }, /* 92 */
- { 19, 9, 37, }, /* 93 */
- { 19, 9, 64, }, /* 94 */
- { 19, 9, 63, }, /* 95 */
- { 19, 5, 0, }, /* 96 */
- { 19, 9, 32, }, /* 97 */
- { 19, 5, -38, }, /* 98 */
- { 19, 5, -37, }, /* 99 */
- { 19, 5, -32, }, /* 100 */
- { 19, 5, -31, }, /* 101 */
- { 19, 5, -64, }, /* 102 */
- { 19, 5, -63, }, /* 103 */
- { 19, 9, 8, }, /* 104 */
- { 19, 5, -62, }, /* 105 */
- { 19, 5, -57, }, /* 106 */
- { 19, 9, 0, }, /* 107 */
- { 19, 5, -47, }, /* 108 */
- { 19, 5, -54, }, /* 109 */
- { 19, 5, -8, }, /* 110 */
- { 10, 9, 1, }, /* 111 */
- { 10, 5, -1, }, /* 112 */
- { 19, 5, -86, }, /* 113 */
- { 19, 5, -80, }, /* 114 */
- { 19, 5, 7, }, /* 115 */
- { 19, 9, -60, }, /* 116 */
- { 19, 5, -96, }, /* 117 */
- { 19, 25, 0, }, /* 118 */
- { 19, 9, -7, }, /* 119 */
- { 19, 9, -130, }, /* 120 */
- { 12, 9, 80, }, /* 121 */
- { 12, 9, 32, }, /* 122 */
- { 12, 5, -32, }, /* 123 */
- { 12, 5, -80, }, /* 124 */
- { 12, 9, 1, }, /* 125 */
- { 12, 5, -1, }, /* 126 */
- { 12, 26, 0, }, /* 127 */
- { 12, 12, 0, }, /* 128 */
- { 12, 11, 0, }, /* 129 */
- { 12, 9, 15, }, /* 130 */
- { 12, 5, -15, }, /* 131 */
- { 1, 9, 48, }, /* 132 */
- { 1, 6, 0, }, /* 133 */
- { 1, 21, 0, }, /* 134 */
- { 1, 5, -48, }, /* 135 */
- { 1, 5, 0, }, /* 136 */
- { 1, 17, 0, }, /* 137 */
- { 25, 12, 0, }, /* 138 */
- { 25, 17, 0, }, /* 139 */
- { 25, 21, 0, }, /* 140 */
- { 25, 7, 0, }, /* 141 */
- { 0, 25, 0, }, /* 142 */
- { 0, 21, 0, }, /* 143 */
- { 0, 23, 0, }, /* 144 */
- { 0, 26, 0, }, /* 145 */
- { 0, 12, 0, }, /* 146 */
- { 0, 7, 0, }, /* 147 */
- { 0, 11, 0, }, /* 148 */
- { 0, 6, 0, }, /* 149 */
- { 0, 13, 0, }, /* 150 */
- { 49, 21, 0, }, /* 151 */
- { 49, 1, 0, }, /* 152 */
- { 49, 7, 0, }, /* 153 */
- { 49, 12, 0, }, /* 154 */
- { 55, 7, 0, }, /* 155 */
- { 55, 12, 0, }, /* 156 */
- { 63, 13, 0, }, /* 157 */
- { 63, 7, 0, }, /* 158 */
- { 63, 12, 0, }, /* 159 */
- { 63, 6, 0, }, /* 160 */
- { 63, 26, 0, }, /* 161 */
- { 63, 21, 0, }, /* 162 */
- { 89, 7, 0, }, /* 163 */
- { 89, 12, 0, }, /* 164 */
- { 89, 6, 0, }, /* 165 */
- { 89, 21, 0, }, /* 166 */
- { 14, 12, 0, }, /* 167 */
- { 14, 10, 0, }, /* 168 */
- { 14, 7, 0, }, /* 169 */
- { 14, 13, 0, }, /* 170 */
- { 14, 6, 0, }, /* 171 */
- { 2, 12, 0, }, /* 172 */
- { 2, 10, 0, }, /* 173 */
- { 2, 7, 0, }, /* 174 */
- { 2, 13, 0, }, /* 175 */
- { 2, 23, 0, }, /* 176 */
- { 2, 15, 0, }, /* 177 */
- { 2, 26, 0, }, /* 178 */
- { 21, 12, 0, }, /* 179 */
- { 21, 10, 0, }, /* 180 */
- { 21, 7, 0, }, /* 181 */
- { 21, 13, 0, }, /* 182 */
- { 20, 12, 0, }, /* 183 */
- { 20, 10, 0, }, /* 184 */
- { 20, 7, 0, }, /* 185 */
- { 20, 13, 0, }, /* 186 */
- { 20, 23, 0, }, /* 187 */
- { 43, 12, 0, }, /* 188 */
- { 43, 10, 0, }, /* 189 */
- { 43, 7, 0, }, /* 190 */
- { 43, 13, 0, }, /* 191 */
- { 43, 26, 0, }, /* 192 */
- { 53, 12, 0, }, /* 193 */
- { 53, 7, 0, }, /* 194 */
- { 53, 10, 0, }, /* 195 */
- { 53, 13, 0, }, /* 196 */
- { 53, 15, 0, }, /* 197 */
- { 53, 26, 0, }, /* 198 */
- { 53, 23, 0, }, /* 199 */
- { 54, 10, 0, }, /* 200 */
- { 54, 7, 0, }, /* 201 */
- { 54, 12, 0, }, /* 202 */
- { 54, 13, 0, }, /* 203 */
- { 54, 15, 0, }, /* 204 */
- { 54, 26, 0, }, /* 205 */
- { 28, 10, 0, }, /* 206 */
- { 28, 7, 0, }, /* 207 */
- { 28, 12, 0, }, /* 208 */
- { 28, 13, 0, }, /* 209 */
- { 36, 10, 0, }, /* 210 */
- { 36, 7, 0, }, /* 211 */
- { 36, 12, 0, }, /* 212 */
- { 36, 13, 0, }, /* 213 */
- { 36, 15, 0, }, /* 214 */
- { 36, 26, 0, }, /* 215 */
- { 47, 10, 0, }, /* 216 */
- { 47, 7, 0, }, /* 217 */
- { 47, 12, 0, }, /* 218 */
- { 47, 21, 0, }, /* 219 */
- { 56, 7, 0, }, /* 220 */
- { 56, 12, 0, }, /* 221 */
- { 56, 6, 0, }, /* 222 */
- { 56, 21, 0, }, /* 223 */
- { 56, 13, 0, }, /* 224 */
- { 32, 7, 0, }, /* 225 */
- { 32, 12, 0, }, /* 226 */
- { 32, 6, 0, }, /* 227 */
- { 32, 13, 0, }, /* 228 */
- { 57, 7, 0, }, /* 229 */
- { 57, 26, 0, }, /* 230 */
- { 57, 21, 0, }, /* 231 */
- { 57, 12, 0, }, /* 232 */
- { 57, 13, 0, }, /* 233 */
- { 57, 15, 0, }, /* 234 */
- { 57, 22, 0, }, /* 235 */
- { 57, 18, 0, }, /* 236 */
- { 57, 10, 0, }, /* 237 */
- { 38, 7, 0, }, /* 238 */
- { 38, 10, 0, }, /* 239 */
- { 38, 12, 0, }, /* 240 */
- { 38, 13, 0, }, /* 241 */
- { 38, 21, 0, }, /* 242 */
- { 38, 26, 0, }, /* 243 */
- { 16, 9, 7264, }, /* 244 */
- { 16, 7, 0, }, /* 245 */
- { 16, 6, 0, }, /* 246 */
- { 23, 7, 0, }, /* 247 */
- { 15, 7, 0, }, /* 248 */
- { 15, 12, 0, }, /* 249 */
- { 15, 26, 0, }, /* 250 */
- { 15, 21, 0, }, /* 251 */
- { 15, 15, 0, }, /* 252 */
- { 8, 7, 0, }, /* 253 */
- { 7, 17, 0, }, /* 254 */
- { 7, 7, 0, }, /* 255 */
- { 7, 21, 0, }, /* 256 */
- { 40, 29, 0, }, /* 257 */
- { 40, 7, 0, }, /* 258 */
- { 40, 22, 0, }, /* 259 */
- { 40, 18, 0, }, /* 260 */
- { 45, 7, 0, }, /* 261 */
- { 45, 14, 0, }, /* 262 */
- { 50, 7, 0, }, /* 263 */
- { 50, 12, 0, }, /* 264 */
- { 24, 7, 0, }, /* 265 */
- { 24, 12, 0, }, /* 266 */
- { 6, 7, 0, }, /* 267 */
- { 6, 12, 0, }, /* 268 */
- { 51, 7, 0, }, /* 269 */
- { 51, 12, 0, }, /* 270 */
- { 31, 7, 0, }, /* 271 */
- { 31, 1, 0, }, /* 272 */
- { 31, 10, 0, }, /* 273 */
- { 31, 12, 0, }, /* 274 */
- { 31, 21, 0, }, /* 275 */
- { 31, 6, 0, }, /* 276 */
- { 31, 23, 0, }, /* 277 */
- { 31, 13, 0, }, /* 278 */
- { 31, 15, 0, }, /* 279 */
- { 37, 21, 0, }, /* 280 */
- { 37, 17, 0, }, /* 281 */
- { 37, 12, 0, }, /* 282 */
- { 37, 29, 0, }, /* 283 */
- { 37, 13, 0, }, /* 284 */
- { 37, 7, 0, }, /* 285 */
- { 37, 6, 0, }, /* 286 */
- { 34, 7, 0, }, /* 287 */
- { 34, 12, 0, }, /* 288 */
- { 34, 10, 0, }, /* 289 */
- { 34, 26, 0, }, /* 290 */
- { 34, 21, 0, }, /* 291 */
- { 34, 13, 0, }, /* 292 */
- { 52, 7, 0, }, /* 293 */
- { 39, 7, 0, }, /* 294 */
- { 39, 10, 0, }, /* 295 */
- { 39, 13, 0, }, /* 296 */
- { 39, 21, 0, }, /* 297 */
- { 31, 26, 0, }, /* 298 */
- { 5, 7, 0, }, /* 299 */
- { 5, 12, 0, }, /* 300 */
- { 5, 10, 0, }, /* 301 */
- { 5, 21, 0, }, /* 302 */
- { 90, 7, 0, }, /* 303 */
- { 90, 10, 0, }, /* 304 */
- { 90, 12, 0, }, /* 305 */
- { 90, 13, 0, }, /* 306 */
- { 90, 21, 0, }, /* 307 */
- { 90, 6, 0, }, /* 308 */
- { 61, 12, 0, }, /* 309 */
- { 61, 10, 0, }, /* 310 */
- { 61, 7, 0, }, /* 311 */
- { 61, 13, 0, }, /* 312 */
- { 61, 21, 0, }, /* 313 */
- { 61, 26, 0, }, /* 314 */
- { 75, 12, 0, }, /* 315 */
- { 75, 10, 0, }, /* 316 */
- { 75, 7, 0, }, /* 317 */
- { 75, 13, 0, }, /* 318 */
- { 69, 7, 0, }, /* 319 */
- { 69, 10, 0, }, /* 320 */
- { 69, 12, 0, }, /* 321 */
- { 69, 21, 0, }, /* 322 */
- { 69, 13, 0, }, /* 323 */
- { 72, 13, 0, }, /* 324 */
- { 72, 7, 0, }, /* 325 */
- { 72, 6, 0, }, /* 326 */
- { 72, 21, 0, }, /* 327 */
- { 9, 10, 0, }, /* 328 */
- { 9, 7, 0, }, /* 329 */
- { 12, 5, 0, }, /* 330 */
- { 12, 6, 0, }, /* 331 */
- { 33, 5, 35332, }, /* 332 */
- { 33, 5, 3814, }, /* 333 */
- { 33, 5, -59, }, /* 334 */
- { 33, 9, -7615, }, /* 335 */
- { 19, 5, 8, }, /* 336 */
- { 19, 9, -8, }, /* 337 */
- { 19, 5, 74, }, /* 338 */
- { 19, 5, 86, }, /* 339 */
- { 19, 5, 100, }, /* 340 */
- { 19, 5, 128, }, /* 341 */
- { 19, 5, 112, }, /* 342 */
- { 19, 5, 126, }, /* 343 */
- { 19, 8, -8, }, /* 344 */
- { 19, 5, 9, }, /* 345 */
- { 19, 9, -74, }, /* 346 */
- { 19, 8, -9, }, /* 347 */
- { 19, 5, -7205, }, /* 348 */
- { 19, 9, -86, }, /* 349 */
- { 19, 9, -100, }, /* 350 */
- { 19, 9, -112, }, /* 351 */
- { 19, 9, -128, }, /* 352 */
- { 19, 9, -126, }, /* 353 */
- { 27, 1, 0, }, /* 354 */
- { 9, 27, 0, }, /* 355 */
- { 9, 28, 0, }, /* 356 */
- { 27, 11, 0, }, /* 357 */
- { 9, 9, 0, }, /* 358 */
- { 9, 5, 0, }, /* 359 */
- { 19, 9, -7517, }, /* 360 */
- { 33, 9, -8383, }, /* 361 */
- { 33, 9, -8262, }, /* 362 */
- { 33, 9, 28, }, /* 363 */
- { 33, 5, -28, }, /* 364 */
- { 33, 14, 16, }, /* 365 */
- { 33, 14, -16, }, /* 366 */
- { 33, 14, 0, }, /* 367 */
- { 9, 26, 26, }, /* 368 */
- { 9, 26, -26, }, /* 369 */
- { 4, 26, 0, }, /* 370 */
- { 17, 9, 48, }, /* 371 */
- { 17, 5, -48, }, /* 372 */
- { 33, 9, -10743, }, /* 373 */
- { 33, 9, -3814, }, /* 374 */
- { 33, 9, -10727, }, /* 375 */
- { 33, 5, -10795, }, /* 376 */
- { 33, 5, -10792, }, /* 377 */
- { 33, 9, -10780, }, /* 378 */
- { 33, 9, -10749, }, /* 379 */
- { 33, 9, -10783, }, /* 380 */
- { 33, 9, -10782, }, /* 381 */
- { 33, 9, -10815, }, /* 382 */
- { 10, 5, 0, }, /* 383 */
- { 10, 26, 0, }, /* 384 */
- { 10, 12, 0, }, /* 385 */
- { 10, 21, 0, }, /* 386 */
- { 10, 15, 0, }, /* 387 */
- { 16, 5, -7264, }, /* 388 */
- { 58, 7, 0, }, /* 389 */
- { 58, 6, 0, }, /* 390 */
- { 22, 26, 0, }, /* 391 */
- { 22, 6, 0, }, /* 392 */
- { 22, 14, 0, }, /* 393 */
- { 26, 7, 0, }, /* 394 */
- { 26, 6, 0, }, /* 395 */
- { 29, 7, 0, }, /* 396 */
- { 29, 6, 0, }, /* 397 */
- { 3, 7, 0, }, /* 398 */
- { 23, 26, 0, }, /* 399 */
- { 29, 26, 0, }, /* 400 */
- { 22, 7, 0, }, /* 401 */
- { 60, 7, 0, }, /* 402 */
- { 60, 6, 0, }, /* 403 */
- { 60, 26, 0, }, /* 404 */
- { 85, 7, 0, }, /* 405 */
- { 85, 6, 0, }, /* 406 */
- { 85, 21, 0, }, /* 407 */
- { 76, 7, 0, }, /* 408 */
- { 76, 6, 0, }, /* 409 */
- { 76, 21, 0, }, /* 410 */
- { 76, 13, 0, }, /* 411 */
- { 12, 7, 0, }, /* 412 */
- { 12, 21, 0, }, /* 413 */
- { 78, 7, 0, }, /* 414 */
- { 78, 14, 0, }, /* 415 */
- { 78, 12, 0, }, /* 416 */
- { 78, 21, 0, }, /* 417 */
- { 33, 9, -35332, }, /* 418 */
- { 48, 7, 0, }, /* 419 */
- { 48, 12, 0, }, /* 420 */
- { 48, 10, 0, }, /* 421 */
- { 48, 26, 0, }, /* 422 */
- { 64, 7, 0, }, /* 423 */
- { 64, 21, 0, }, /* 424 */
- { 74, 10, 0, }, /* 425 */
- { 74, 7, 0, }, /* 426 */
- { 74, 12, 0, }, /* 427 */
- { 74, 21, 0, }, /* 428 */
- { 74, 13, 0, }, /* 429 */
- { 14, 21, 0, }, /* 430 */
- { 68, 13, 0, }, /* 431 */
- { 68, 7, 0, }, /* 432 */
- { 68, 12, 0, }, /* 433 */
- { 68, 21, 0, }, /* 434 */
- { 73, 7, 0, }, /* 435 */
- { 73, 12, 0, }, /* 436 */
- { 73, 10, 0, }, /* 437 */
- { 73, 21, 0, }, /* 438 */
- { 83, 12, 0, }, /* 439 */
- { 83, 10, 0, }, /* 440 */
- { 83, 7, 0, }, /* 441 */
- { 83, 21, 0, }, /* 442 */
- { 83, 6, 0, }, /* 443 */
- { 83, 13, 0, }, /* 444 */
- { 67, 7, 0, }, /* 445 */
- { 67, 12, 0, }, /* 446 */
- { 67, 10, 0, }, /* 447 */
- { 67, 13, 0, }, /* 448 */
- { 67, 21, 0, }, /* 449 */
- { 38, 6, 0, }, /* 450 */
- { 91, 7, 0, }, /* 451 */
- { 91, 12, 0, }, /* 452 */
- { 91, 6, 0, }, /* 453 */
- { 91, 21, 0, }, /* 454 */
- { 86, 7, 0, }, /* 455 */
- { 86, 10, 0, }, /* 456 */
- { 86, 12, 0, }, /* 457 */
- { 86, 21, 0, }, /* 458 */
- { 86, 13, 0, }, /* 459 */
- { 9, 4, 0, }, /* 460 */
- { 9, 3, 0, }, /* 461 */
- { 25, 25, 0, }, /* 462 */
- { 35, 7, 0, }, /* 463 */
- { 19, 14, 0, }, /* 464 */
- { 19, 15, 0, }, /* 465 */
- { 19, 26, 0, }, /* 466 */
- { 70, 7, 0, }, /* 467 */
- { 66, 7, 0, }, /* 468 */
- { 41, 7, 0, }, /* 469 */
- { 41, 15, 0, }, /* 470 */
- { 18, 7, 0, }, /* 471 */
- { 18, 14, 0, }, /* 472 */
- { 59, 7, 0, }, /* 473 */
- { 59, 21, 0, }, /* 474 */
- { 42, 7, 0, }, /* 475 */
- { 42, 21, 0, }, /* 476 */
- { 42, 14, 0, }, /* 477 */
- { 13, 9, 40, }, /* 478 */
- { 13, 5, -40, }, /* 479 */
- { 46, 7, 0, }, /* 480 */
- { 44, 7, 0, }, /* 481 */
- { 44, 13, 0, }, /* 482 */
- { 11, 7, 0, }, /* 483 */
- { 80, 7, 0, }, /* 484 */
- { 80, 21, 0, }, /* 485 */
- { 80, 15, 0, }, /* 486 */
- { 65, 7, 0, }, /* 487 */
- { 65, 15, 0, }, /* 488 */
- { 65, 21, 0, }, /* 489 */
- { 71, 7, 0, }, /* 490 */
- { 71, 21, 0, }, /* 491 */
- { 30, 7, 0, }, /* 492 */
- { 30, 12, 0, }, /* 493 */
- { 30, 15, 0, }, /* 494 */
- { 30, 21, 0, }, /* 495 */
- { 87, 7, 0, }, /* 496 */
- { 87, 15, 0, }, /* 497 */
- { 87, 21, 0, }, /* 498 */
- { 77, 7, 0, }, /* 499 */
- { 77, 21, 0, }, /* 500 */
- { 82, 7, 0, }, /* 501 */
- { 82, 15, 0, }, /* 502 */
- { 81, 7, 0, }, /* 503 */
- { 81, 15, 0, }, /* 504 */
- { 88, 7, 0, }, /* 505 */
- { 0, 15, 0, }, /* 506 */
- { 84, 12, 0, }, /* 507 */
- { 84, 10, 0, }, /* 508 */
- { 84, 7, 0, }, /* 509 */
- { 84, 21, 0, }, /* 510 */
- { 84, 1, 0, }, /* 511 */
- { 62, 7, 0, }, /* 512 */
- { 62, 14, 0, }, /* 513 */
- { 62, 21, 0, }, /* 514 */
- { 79, 7, 0, }, /* 515 */
- { 19, 12, 0, }, /* 516 */
- { 26, 26, 0, }, /* 517 */
+ { 33, 5, 42280, }, /* 70 */
+ { 33, 5, 42308, }, /* 71 */
+ { 33, 5, -209, }, /* 72 */
+ { 33, 5, -211, }, /* 73 */
+ { 33, 5, 10743, }, /* 74 */
+ { 33, 5, 10749, }, /* 75 */
+ { 33, 5, -213, }, /* 76 */
+ { 33, 5, -214, }, /* 77 */
+ { 33, 5, 10727, }, /* 78 */
+ { 33, 5, -218, }, /* 79 */
+ { 33, 5, -69, }, /* 80 */
+ { 33, 5, -217, }, /* 81 */
+ { 33, 5, -71, }, /* 82 */
+ { 33, 5, -219, }, /* 83 */
+ { 33, 6, 0, }, /* 84 */
+ { 9, 6, 0, }, /* 85 */
+ { 3, 24, 0, }, /* 86 */
+ { 27, 12, 0, }, /* 87 */
+ { 27, 12, 84, }, /* 88 */
+ { 19, 9, 1, }, /* 89 */
+ { 19, 5, -1, }, /* 90 */
+ { 19, 24, 0, }, /* 91 */
+ { 9, 2, 0, }, /* 92 */
+ { 19, 6, 0, }, /* 93 */
+ { 19, 5, 130, }, /* 94 */
+ { 19, 9, 38, }, /* 95 */
+ { 19, 9, 37, }, /* 96 */
+ { 19, 9, 64, }, /* 97 */
+ { 19, 9, 63, }, /* 98 */
+ { 19, 5, 0, }, /* 99 */
+ { 19, 9, 32, }, /* 100 */
+ { 19, 5, -38, }, /* 101 */
+ { 19, 5, -37, }, /* 102 */
+ { 19, 5, -32, }, /* 103 */
+ { 19, 5, -31, }, /* 104 */
+ { 19, 5, -64, }, /* 105 */
+ { 19, 5, -63, }, /* 106 */
+ { 19, 9, 8, }, /* 107 */
+ { 19, 5, -62, }, /* 108 */
+ { 19, 5, -57, }, /* 109 */
+ { 19, 9, 0, }, /* 110 */
+ { 19, 5, -47, }, /* 111 */
+ { 19, 5, -54, }, /* 112 */
+ { 19, 5, -8, }, /* 113 */
+ { 10, 9, 1, }, /* 114 */
+ { 10, 5, -1, }, /* 115 */
+ { 19, 5, -86, }, /* 116 */
+ { 19, 5, -80, }, /* 117 */
+ { 19, 5, 7, }, /* 118 */
+ { 19, 9, -60, }, /* 119 */
+ { 19, 5, -96, }, /* 120 */
+ { 19, 25, 0, }, /* 121 */
+ { 19, 9, -7, }, /* 122 */
+ { 19, 9, -130, }, /* 123 */
+ { 12, 9, 80, }, /* 124 */
+ { 12, 9, 32, }, /* 125 */
+ { 12, 5, -32, }, /* 126 */
+ { 12, 5, -80, }, /* 127 */
+ { 12, 9, 1, }, /* 128 */
+ { 12, 5, -1, }, /* 129 */
+ { 12, 26, 0, }, /* 130 */
+ { 12, 12, 0, }, /* 131 */
+ { 12, 11, 0, }, /* 132 */
+ { 12, 9, 15, }, /* 133 */
+ { 12, 5, -15, }, /* 134 */
+ { 1, 9, 48, }, /* 135 */
+ { 1, 6, 0, }, /* 136 */
+ { 1, 21, 0, }, /* 137 */
+ { 1, 5, -48, }, /* 138 */
+ { 1, 5, 0, }, /* 139 */
+ { 1, 17, 0, }, /* 140 */
+ { 1, 23, 0, }, /* 141 */
+ { 25, 12, 0, }, /* 142 */
+ { 25, 17, 0, }, /* 143 */
+ { 25, 21, 0, }, /* 144 */
+ { 25, 7, 0, }, /* 145 */
+ { 0, 1, 0, }, /* 146 */
+ { 0, 25, 0, }, /* 147 */
+ { 0, 21, 0, }, /* 148 */
+ { 0, 23, 0, }, /* 149 */
+ { 0, 26, 0, }, /* 150 */
+ { 0, 12, 0, }, /* 151 */
+ { 0, 7, 0, }, /* 152 */
+ { 0, 6, 0, }, /* 153 */
+ { 0, 13, 0, }, /* 154 */
+ { 49, 21, 0, }, /* 155 */
+ { 49, 1, 0, }, /* 156 */
+ { 49, 7, 0, }, /* 157 */
+ { 49, 12, 0, }, /* 158 */
+ { 55, 7, 0, }, /* 159 */
+ { 55, 12, 0, }, /* 160 */
+ { 63, 13, 0, }, /* 161 */
+ { 63, 7, 0, }, /* 162 */
+ { 63, 12, 0, }, /* 163 */
+ { 63, 6, 0, }, /* 164 */
+ { 63, 26, 0, }, /* 165 */
+ { 63, 21, 0, }, /* 166 */
+ { 89, 7, 0, }, /* 167 */
+ { 89, 12, 0, }, /* 168 */
+ { 89, 6, 0, }, /* 169 */
+ { 89, 21, 0, }, /* 170 */
+ { 94, 7, 0, }, /* 171 */
+ { 94, 12, 0, }, /* 172 */
+ { 94, 21, 0, }, /* 173 */
+ { 14, 12, 0, }, /* 174 */
+ { 14, 10, 0, }, /* 175 */
+ { 14, 7, 0, }, /* 176 */
+ { 14, 13, 0, }, /* 177 */
+ { 14, 21, 0, }, /* 178 */
+ { 14, 6, 0, }, /* 179 */
+ { 2, 12, 0, }, /* 180 */
+ { 2, 10, 0, }, /* 181 */
+ { 2, 7, 0, }, /* 182 */
+ { 2, 13, 0, }, /* 183 */
+ { 2, 23, 0, }, /* 184 */
+ { 2, 15, 0, }, /* 185 */
+ { 2, 26, 0, }, /* 186 */
+ { 21, 12, 0, }, /* 187 */
+ { 21, 10, 0, }, /* 188 */
+ { 21, 7, 0, }, /* 189 */
+ { 21, 13, 0, }, /* 190 */
+ { 20, 12, 0, }, /* 191 */
+ { 20, 10, 0, }, /* 192 */
+ { 20, 7, 0, }, /* 193 */
+ { 20, 13, 0, }, /* 194 */
+ { 20, 21, 0, }, /* 195 */
+ { 20, 23, 0, }, /* 196 */
+ { 43, 12, 0, }, /* 197 */
+ { 43, 10, 0, }, /* 198 */
+ { 43, 7, 0, }, /* 199 */
+ { 43, 13, 0, }, /* 200 */
+ { 43, 26, 0, }, /* 201 */
+ { 43, 15, 0, }, /* 202 */
+ { 53, 12, 0, }, /* 203 */
+ { 53, 7, 0, }, /* 204 */
+ { 53, 10, 0, }, /* 205 */
+ { 53, 13, 0, }, /* 206 */
+ { 53, 15, 0, }, /* 207 */
+ { 53, 26, 0, }, /* 208 */
+ { 53, 23, 0, }, /* 209 */
+ { 54, 10, 0, }, /* 210 */
+ { 54, 7, 0, }, /* 211 */
+ { 54, 12, 0, }, /* 212 */
+ { 54, 13, 0, }, /* 213 */
+ { 54, 15, 0, }, /* 214 */
+ { 54, 26, 0, }, /* 215 */
+ { 28, 10, 0, }, /* 216 */
+ { 28, 7, 0, }, /* 217 */
+ { 28, 12, 0, }, /* 218 */
+ { 28, 13, 0, }, /* 219 */
+ { 36, 10, 0, }, /* 220 */
+ { 36, 7, 0, }, /* 221 */
+ { 36, 12, 0, }, /* 222 */
+ { 36, 13, 0, }, /* 223 */
+ { 36, 15, 0, }, /* 224 */
+ { 36, 26, 0, }, /* 225 */
+ { 47, 10, 0, }, /* 226 */
+ { 47, 7, 0, }, /* 227 */
+ { 47, 12, 0, }, /* 228 */
+ { 47, 21, 0, }, /* 229 */
+ { 56, 7, 0, }, /* 230 */
+ { 56, 12, 0, }, /* 231 */
+ { 56, 6, 0, }, /* 232 */
+ { 56, 21, 0, }, /* 233 */
+ { 56, 13, 0, }, /* 234 */
+ { 32, 7, 0, }, /* 235 */
+ { 32, 12, 0, }, /* 236 */
+ { 32, 6, 0, }, /* 237 */
+ { 32, 13, 0, }, /* 238 */
+ { 57, 7, 0, }, /* 239 */
+ { 57, 26, 0, }, /* 240 */
+ { 57, 21, 0, }, /* 241 */
+ { 57, 12, 0, }, /* 242 */
+ { 57, 13, 0, }, /* 243 */
+ { 57, 15, 0, }, /* 244 */
+ { 57, 22, 0, }, /* 245 */
+ { 57, 18, 0, }, /* 246 */
+ { 57, 10, 0, }, /* 247 */
+ { 38, 7, 0, }, /* 248 */
+ { 38, 10, 0, }, /* 249 */
+ { 38, 12, 0, }, /* 250 */
+ { 38, 13, 0, }, /* 251 */
+ { 38, 21, 0, }, /* 252 */
+ { 38, 26, 0, }, /* 253 */
+ { 16, 9, 7264, }, /* 254 */
+ { 16, 7, 0, }, /* 255 */
+ { 16, 6, 0, }, /* 256 */
+ { 23, 7, 0, }, /* 257 */
+ { 15, 7, 0, }, /* 258 */
+ { 15, 12, 0, }, /* 259 */
+ { 15, 21, 0, }, /* 260 */
+ { 15, 15, 0, }, /* 261 */
+ { 15, 26, 0, }, /* 262 */
+ { 8, 7, 0, }, /* 263 */
+ { 7, 17, 0, }, /* 264 */
+ { 7, 7, 0, }, /* 265 */
+ { 7, 21, 0, }, /* 266 */
+ { 40, 29, 0, }, /* 267 */
+ { 40, 7, 0, }, /* 268 */
+ { 40, 22, 0, }, /* 269 */
+ { 40, 18, 0, }, /* 270 */
+ { 45, 7, 0, }, /* 271 */
+ { 45, 14, 0, }, /* 272 */
+ { 50, 7, 0, }, /* 273 */
+ { 50, 12, 0, }, /* 274 */
+ { 24, 7, 0, }, /* 275 */
+ { 24, 12, 0, }, /* 276 */
+ { 6, 7, 0, }, /* 277 */
+ { 6, 12, 0, }, /* 278 */
+ { 51, 7, 0, }, /* 279 */
+ { 51, 12, 0, }, /* 280 */
+ { 31, 7, 0, }, /* 281 */
+ { 31, 12, 0, }, /* 282 */
+ { 31, 10, 0, }, /* 283 */
+ { 31, 21, 0, }, /* 284 */
+ { 31, 6, 0, }, /* 285 */
+ { 31, 23, 0, }, /* 286 */
+ { 31, 13, 0, }, /* 287 */
+ { 31, 15, 0, }, /* 288 */
+ { 37, 21, 0, }, /* 289 */
+ { 37, 17, 0, }, /* 290 */
+ { 37, 12, 0, }, /* 291 */
+ { 37, 29, 0, }, /* 292 */
+ { 37, 13, 0, }, /* 293 */
+ { 37, 7, 0, }, /* 294 */
+ { 37, 6, 0, }, /* 295 */
+ { 34, 7, 0, }, /* 296 */
+ { 34, 12, 0, }, /* 297 */
+ { 34, 10, 0, }, /* 298 */
+ { 34, 26, 0, }, /* 299 */
+ { 34, 21, 0, }, /* 300 */
+ { 34, 13, 0, }, /* 301 */
+ { 52, 7, 0, }, /* 302 */
+ { 39, 7, 0, }, /* 303 */
+ { 39, 10, 0, }, /* 304 */
+ { 39, 13, 0, }, /* 305 */
+ { 39, 15, 0, }, /* 306 */
+ { 39, 26, 0, }, /* 307 */
+ { 31, 26, 0, }, /* 308 */
+ { 5, 7, 0, }, /* 309 */
+ { 5, 12, 0, }, /* 310 */
+ { 5, 10, 0, }, /* 311 */
+ { 5, 21, 0, }, /* 312 */
+ { 90, 7, 0, }, /* 313 */
+ { 90, 10, 0, }, /* 314 */
+ { 90, 12, 0, }, /* 315 */
+ { 90, 13, 0, }, /* 316 */
+ { 90, 21, 0, }, /* 317 */
+ { 90, 6, 0, }, /* 318 */
+ { 61, 12, 0, }, /* 319 */
+ { 61, 10, 0, }, /* 320 */
+ { 61, 7, 0, }, /* 321 */
+ { 61, 13, 0, }, /* 322 */
+ { 61, 21, 0, }, /* 323 */
+ { 61, 26, 0, }, /* 324 */
+ { 75, 12, 0, }, /* 325 */
+ { 75, 10, 0, }, /* 326 */
+ { 75, 7, 0, }, /* 327 */
+ { 75, 13, 0, }, /* 328 */
+ { 92, 7, 0, }, /* 329 */
+ { 92, 12, 0, }, /* 330 */
+ { 92, 10, 0, }, /* 331 */
+ { 92, 21, 0, }, /* 332 */
+ { 69, 7, 0, }, /* 333 */
+ { 69, 10, 0, }, /* 334 */
+ { 69, 12, 0, }, /* 335 */
+ { 69, 21, 0, }, /* 336 */
+ { 69, 13, 0, }, /* 337 */
+ { 72, 13, 0, }, /* 338 */
+ { 72, 7, 0, }, /* 339 */
+ { 72, 6, 0, }, /* 340 */
+ { 72, 21, 0, }, /* 341 */
+ { 75, 21, 0, }, /* 342 */
+ { 9, 10, 0, }, /* 343 */
+ { 9, 7, 0, }, /* 344 */
+ { 12, 5, 0, }, /* 345 */
+ { 12, 6, 0, }, /* 346 */
+ { 33, 5, 35332, }, /* 347 */
+ { 33, 5, 3814, }, /* 348 */
+ { 33, 5, -59, }, /* 349 */
+ { 33, 9, -7615, }, /* 350 */
+ { 19, 5, 8, }, /* 351 */
+ { 19, 9, -8, }, /* 352 */
+ { 19, 5, 74, }, /* 353 */
+ { 19, 5, 86, }, /* 354 */
+ { 19, 5, 100, }, /* 355 */
+ { 19, 5, 128, }, /* 356 */
+ { 19, 5, 112, }, /* 357 */
+ { 19, 5, 126, }, /* 358 */
+ { 19, 8, -8, }, /* 359 */
+ { 19, 5, 9, }, /* 360 */
+ { 19, 9, -74, }, /* 361 */
+ { 19, 8, -9, }, /* 362 */
+ { 19, 5, -7205, }, /* 363 */
+ { 19, 9, -86, }, /* 364 */
+ { 19, 9, -100, }, /* 365 */
+ { 19, 9, -112, }, /* 366 */
+ { 19, 9, -128, }, /* 367 */
+ { 19, 9, -126, }, /* 368 */
+ { 27, 1, 0, }, /* 369 */
+ { 9, 27, 0, }, /* 370 */
+ { 9, 28, 0, }, /* 371 */
+ { 27, 11, 0, }, /* 372 */
+ { 9, 9, 0, }, /* 373 */
+ { 9, 5, 0, }, /* 374 */
+ { 19, 9, -7517, }, /* 375 */
+ { 33, 9, -8383, }, /* 376 */
+ { 33, 9, -8262, }, /* 377 */
+ { 33, 9, 28, }, /* 378 */
+ { 33, 5, -28, }, /* 379 */
+ { 33, 14, 16, }, /* 380 */
+ { 33, 14, -16, }, /* 381 */
+ { 33, 14, 0, }, /* 382 */
+ { 9, 26, 26, }, /* 383 */
+ { 9, 26, -26, }, /* 384 */
+ { 4, 26, 0, }, /* 385 */
+ { 17, 9, 48, }, /* 386 */
+ { 17, 5, -48, }, /* 387 */
+ { 33, 9, -10743, }, /* 388 */
+ { 33, 9, -3814, }, /* 389 */
+ { 33, 9, -10727, }, /* 390 */
+ { 33, 5, -10795, }, /* 391 */
+ { 33, 5, -10792, }, /* 392 */
+ { 33, 9, -10780, }, /* 393 */
+ { 33, 9, -10749, }, /* 394 */
+ { 33, 9, -10783, }, /* 395 */
+ { 33, 9, -10782, }, /* 396 */
+ { 33, 9, -10815, }, /* 397 */
+ { 10, 5, 0, }, /* 398 */
+ { 10, 26, 0, }, /* 399 */
+ { 10, 12, 0, }, /* 400 */
+ { 10, 21, 0, }, /* 401 */
+ { 10, 15, 0, }, /* 402 */
+ { 16, 5, -7264, }, /* 403 */
+ { 58, 7, 0, }, /* 404 */
+ { 58, 6, 0, }, /* 405 */
+ { 58, 21, 0, }, /* 406 */
+ { 58, 12, 0, }, /* 407 */
+ { 22, 26, 0, }, /* 408 */
+ { 22, 6, 0, }, /* 409 */
+ { 22, 14, 0, }, /* 410 */
+ { 23, 10, 0, }, /* 411 */
+ { 26, 7, 0, }, /* 412 */
+ { 26, 6, 0, }, /* 413 */
+ { 29, 7, 0, }, /* 414 */
+ { 29, 6, 0, }, /* 415 */
+ { 3, 7, 0, }, /* 416 */
+ { 23, 26, 0, }, /* 417 */
+ { 29, 26, 0, }, /* 418 */
+ { 22, 7, 0, }, /* 419 */
+ { 60, 7, 0, }, /* 420 */
+ { 60, 6, 0, }, /* 421 */
+ { 60, 26, 0, }, /* 422 */
+ { 85, 7, 0, }, /* 423 */
+ { 85, 6, 0, }, /* 424 */
+ { 85, 21, 0, }, /* 425 */
+ { 76, 7, 0, }, /* 426 */
+ { 76, 6, 0, }, /* 427 */
+ { 76, 21, 0, }, /* 428 */
+ { 76, 13, 0, }, /* 429 */
+ { 12, 7, 0, }, /* 430 */
+ { 12, 21, 0, }, /* 431 */
+ { 78, 7, 0, }, /* 432 */
+ { 78, 14, 0, }, /* 433 */
+ { 78, 12, 0, }, /* 434 */
+ { 78, 21, 0, }, /* 435 */
+ { 33, 9, -35332, }, /* 436 */
+ { 33, 9, -42280, }, /* 437 */
+ { 33, 9, -42308, }, /* 438 */
+ { 48, 7, 0, }, /* 439 */
+ { 48, 12, 0, }, /* 440 */
+ { 48, 10, 0, }, /* 441 */
+ { 48, 26, 0, }, /* 442 */
+ { 64, 7, 0, }, /* 443 */
+ { 64, 21, 0, }, /* 444 */
+ { 74, 10, 0, }, /* 445 */
+ { 74, 7, 0, }, /* 446 */
+ { 74, 12, 0, }, /* 447 */
+ { 74, 21, 0, }, /* 448 */
+ { 74, 13, 0, }, /* 449 */
+ { 68, 13, 0, }, /* 450 */
+ { 68, 7, 0, }, /* 451 */
+ { 68, 12, 0, }, /* 452 */
+ { 68, 21, 0, }, /* 453 */
+ { 73, 7, 0, }, /* 454 */
+ { 73, 12, 0, }, /* 455 */
+ { 73, 10, 0, }, /* 456 */
+ { 73, 21, 0, }, /* 457 */
+ { 83, 12, 0, }, /* 458 */
+ { 83, 10, 0, }, /* 459 */
+ { 83, 7, 0, }, /* 460 */
+ { 83, 21, 0, }, /* 461 */
+ { 83, 6, 0, }, /* 462 */
+ { 83, 13, 0, }, /* 463 */
+ { 67, 7, 0, }, /* 464 */
+ { 67, 12, 0, }, /* 465 */
+ { 67, 10, 0, }, /* 466 */
+ { 67, 13, 0, }, /* 467 */
+ { 67, 21, 0, }, /* 468 */
+ { 38, 6, 0, }, /* 469 */
+ { 91, 7, 0, }, /* 470 */
+ { 91, 12, 0, }, /* 471 */
+ { 91, 6, 0, }, /* 472 */
+ { 91, 21, 0, }, /* 473 */
+ { 86, 7, 0, }, /* 474 */
+ { 86, 10, 0, }, /* 475 */
+ { 86, 12, 0, }, /* 476 */
+ { 86, 21, 0, }, /* 477 */
+ { 86, 6, 0, }, /* 478 */
+ { 86, 13, 0, }, /* 479 */
+ { 9, 4, 0, }, /* 480 */
+ { 9, 3, 0, }, /* 481 */
+ { 25, 25, 0, }, /* 482 */
+ { 0, 24, 0, }, /* 483 */
+ { 35, 7, 0, }, /* 484 */
+ { 19, 14, 0, }, /* 485 */
+ { 19, 15, 0, }, /* 486 */
+ { 19, 26, 0, }, /* 487 */
+ { 70, 7, 0, }, /* 488 */
+ { 66, 7, 0, }, /* 489 */
+ { 41, 7, 0, }, /* 490 */
+ { 41, 15, 0, }, /* 491 */
+ { 18, 7, 0, }, /* 492 */
+ { 18, 14, 0, }, /* 493 */
+ { 59, 7, 0, }, /* 494 */
+ { 59, 21, 0, }, /* 495 */
+ { 42, 7, 0, }, /* 496 */
+ { 42, 21, 0, }, /* 497 */
+ { 42, 14, 0, }, /* 498 */
+ { 13, 9, 40, }, /* 499 */
+ { 13, 5, -40, }, /* 500 */
+ { 46, 7, 0, }, /* 501 */
+ { 44, 7, 0, }, /* 502 */
+ { 44, 13, 0, }, /* 503 */
+ { 11, 7, 0, }, /* 504 */
+ { 80, 7, 0, }, /* 505 */
+ { 80, 21, 0, }, /* 506 */
+ { 80, 15, 0, }, /* 507 */
+ { 65, 7, 0, }, /* 508 */
+ { 65, 15, 0, }, /* 509 */
+ { 65, 21, 0, }, /* 510 */
+ { 71, 7, 0, }, /* 511 */
+ { 71, 21, 0, }, /* 512 */
+ { 97, 7, 0, }, /* 513 */
+ { 96, 7, 0, }, /* 514 */
+ { 30, 7, 0, }, /* 515 */
+ { 30, 12, 0, }, /* 516 */
+ { 30, 15, 0, }, /* 517 */
+ { 30, 21, 0, }, /* 518 */
+ { 87, 7, 0, }, /* 519 */
+ { 87, 15, 0, }, /* 520 */
+ { 87, 21, 0, }, /* 521 */
+ { 77, 7, 0, }, /* 522 */
+ { 77, 21, 0, }, /* 523 */
+ { 82, 7, 0, }, /* 524 */
+ { 82, 15, 0, }, /* 525 */
+ { 81, 7, 0, }, /* 526 */
+ { 81, 15, 0, }, /* 527 */
+ { 88, 7, 0, }, /* 528 */
+ { 0, 15, 0, }, /* 529 */
+ { 93, 10, 0, }, /* 530 */
+ { 93, 12, 0, }, /* 531 */
+ { 93, 7, 0, }, /* 532 */
+ { 93, 21, 0, }, /* 533 */
+ { 93, 15, 0, }, /* 534 */
+ { 93, 13, 0, }, /* 535 */
+ { 84, 12, 0, }, /* 536 */
+ { 84, 10, 0, }, /* 537 */
+ { 84, 7, 0, }, /* 538 */
+ { 84, 21, 0, }, /* 539 */
+ { 84, 1, 0, }, /* 540 */
+ { 100, 7, 0, }, /* 541 */
+ { 100, 13, 0, }, /* 542 */
+ { 95, 12, 0, }, /* 543 */
+ { 95, 7, 0, }, /* 544 */
+ { 95, 10, 0, }, /* 545 */
+ { 95, 13, 0, }, /* 546 */
+ { 95, 21, 0, }, /* 547 */
+ { 99, 12, 0, }, /* 548 */
+ { 99, 10, 0, }, /* 549 */
+ { 99, 7, 0, }, /* 550 */
+ { 99, 21, 0, }, /* 551 */
+ { 99, 13, 0, }, /* 552 */
+ { 101, 7, 0, }, /* 553 */
+ { 101, 12, 0, }, /* 554 */
+ { 101, 10, 0, }, /* 555 */
+ { 101, 13, 0, }, /* 556 */
+ { 62, 7, 0, }, /* 557 */
+ { 62, 14, 0, }, /* 558 */
+ { 62, 21, 0, }, /* 559 */
+ { 79, 7, 0, }, /* 560 */
+ { 98, 7, 0, }, /* 561 */
+ { 98, 10, 0, }, /* 562 */
+ { 98, 12, 0, }, /* 563 */
+ { 98, 6, 0, }, /* 564 */
+ { 19, 12, 0, }, /* 565 */
+ { 26, 26, 0, }, /* 566 */
};
-const uschar _pcre_ucd_stage1[] = { /* 8704 bytes */
+const pcre_uint8 PRIV(ucd_stage1)[] = { /* 8704 bytes */
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* U+0000 */
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* U+0800 */
32, 33, 34, 34, 35, 36, 37, 38, 39, 40, 40, 40, 41, 42, 43, 44, /* U+1000 */
45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, /* U+1800 */
- 61, 62, 63, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, /* U+2000 */
- 76, 76, 65, 77, 65, 65, 78, 17, 79, 80, 81, 82, 83, 84, 85, 86, /* U+2800 */
+ 61, 62, 63, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 70, 73, 74, /* U+2000 */
+ 75, 75, 65, 76, 65, 65, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, /* U+2800 */
87, 88, 89, 90, 91, 92, 93, 70, 94, 94, 94, 94, 94, 94, 94, 94, /* U+3000 */
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+3800 */
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+4000 */
@@ -575,49 +624,49 @@
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+9000 */
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 96, /* U+9800 */
97, 98, 98, 98, 98, 98, 98, 98, 98, 99,100,100,101,102,103,104, /* U+A000 */
-105,106,107,108,109,110, 17,111, 34, 34, 34, 34, 34, 34, 34, 34, /* U+A800 */
+105,106,107,108,109,110,111,112, 34, 34, 34, 34, 34, 34, 34, 34, /* U+A800 */
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B000 */
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B800 */
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C000 */
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C800 */
- 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,112, /* U+D000 */
-113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, /* U+D800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+E000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+E800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F000 */
-114,114, 94, 94,115,116,117,118,119,119,120,121,122,123,124,125, /* U+F800 */
-126,127,128,129, 17,130,131,132,133,134, 17, 17, 17, 17, 17, 17, /* U+10000 */
-135, 17,136, 17,137, 17,138, 17,139, 17, 17, 17,140, 17, 17, 17, /* U+10800 */
- 17,141, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+11000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+11800 */
-142,142,142,142,142,142,143, 17,144, 17, 17, 17, 17, 17, 17, 17, /* U+12000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+12800 */
-145,145,145,145,145,145,145,145,146, 17, 17, 17, 17, 17, 17, 17, /* U+13000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+13800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+14000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+14800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+15000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+15800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+16000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+16800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+17000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+17800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+18000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+18800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+19000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+19800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1A000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1A800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1B000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1B800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1C000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1C800 */
- 70,147,148,149,150, 17,151, 17,152,153,154,155,156,157,158,159, /* U+1D000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1D800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1E000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1E800 */
-160,161,162,163,164, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1F000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1F800 */
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,113, /* U+D000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+D800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+E000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+E800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F000 */
+115,115, 94, 94,116,117,118,119,120,120,121,122,123,124,125,126, /* U+F800 */
+127,128,129,130, 78,131,132,133,134,135, 78, 78, 78, 78, 78, 78, /* U+10000 */
+136, 78,137,138,139, 78,140, 78,141, 78, 78, 78,142, 78, 78, 78, /* U+10800 */
+143,144,145,146, 78, 78, 78, 78, 78, 78, 78, 78, 78,147, 78, 78, /* U+11000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+11800 */
+148,148,148,148,148,148,149, 78,150, 78, 78, 78, 78, 78, 78, 78, /* U+12000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+12800 */
+151,151,151,151,151,151,151,151,152, 78, 78, 78, 78, 78, 78, 78, /* U+13000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+13800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+14000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+14800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+15000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+15800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+16000 */
+153,153,153,153,154, 78, 78, 78, 78, 78, 78, 78, 78, 78,155,156, /* U+16800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+17000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+17800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+18000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+18800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+19000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+19800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1A000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1A800 */
+157, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1B000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1B800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1C000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1C800 */
+ 70,158,159,160,161, 78,162, 78,163,164,165,166,167,168,169,170, /* U+1D000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1D800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1E000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,171,172, 78, 78, /* U+1E800 */
+173,174,175,176,177, 78,178,179,180,181,182,183,184,185,186, 78, /* U+1F000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+1F800 */
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+20000 */
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+20800 */
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+21000 */
@@ -638,469 +687,469 @@
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+28800 */
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+29000 */
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+29800 */
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,165, 94, 94, /* U+2A000 */
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,187, 94, 94, /* U+2A000 */
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, /* U+2A800 */
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,166, 17, /* U+2B000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2B800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2C000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2C800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2D000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2D800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2E000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2E800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2F000 */
- 94, 94, 94, 94,167, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2F800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+30000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+30800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+31000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+31800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+32000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+32800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+33000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+33800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+34000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+34800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+35000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+35800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+36000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+36800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+37000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+37800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+38000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+38800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+39000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+39800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3A000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3A800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3B000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3B800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3C000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3C800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3D000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3D800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3E000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3E800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3F000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3F800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+40000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+40800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+41000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+41800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+42000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+42800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+43000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+43800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+44000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+44800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+45000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+45800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+46000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+46800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+47000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+47800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+48000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+48800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+49000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+49800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4A000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4A800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4B000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4B800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4C000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4C800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4D000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4D800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4E000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4E800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4F000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4F800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+50000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+50800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+51000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+51800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+52000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+52800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+53000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+53800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+54000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+54800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+55000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+55800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+56000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+56800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+57000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+57800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+58000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+58800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+59000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+59800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5A000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5A800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5B000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5B800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5C000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5C800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5D000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5D800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5E000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5E800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5F000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5F800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+60000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+60800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+61000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+61800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+62000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+62800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+63000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+63800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+64000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+64800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+65000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+65800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+66000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+66800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+67000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+67800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+68000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+68800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+69000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+69800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6A000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6A800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6B000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6B800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6C000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6C800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6D000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6D800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6E000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6E800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6F000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6F800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+70000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+70800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+71000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+71800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+72000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+72800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+73000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+73800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+74000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+74800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+75000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+75800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+76000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+76800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+77000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+77800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+78000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+78800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+79000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+79800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7A000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7A800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7B000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7B800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7C000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7C800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7D000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7D800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7E000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7E800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7F000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7F800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+80000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+80800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+81000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+81800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+82000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+82800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+83000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+83800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+84000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+84800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+85000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+85800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+86000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+86800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+87000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+87800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+88000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+88800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+89000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+89800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8A000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8A800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8B000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8B800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8C000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8C800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8D000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8D800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8E000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8E800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8F000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8F800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+90000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+90800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+91000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+91800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+92000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+92800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+93000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+93800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+94000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+94800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+95000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+95800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+96000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+96800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+97000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+97800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+98000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+98800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+99000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+99800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9A000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9A800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9B000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9B800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9C000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9C800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9D000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9D800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9E000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9E800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9F000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9F800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A0000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A0800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A1000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A1800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A2000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A2800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A3000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A3800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A4000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A4800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A5000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A5800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A6000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A6800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A7000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A7800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A8000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A8800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A9000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A9800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AA000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AA800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AB000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AB800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AC000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AC800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AD000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AD800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AE000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AE800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AF000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AF800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B0000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B0800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B1000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B1800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B2000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B2800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B3000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B3800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B4000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B4800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B5000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B5800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B6000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B6800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B7000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B7800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B8000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B8800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B9000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B9800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BA000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BA800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BB000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BB800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BC000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BC800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BD000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BD800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BE000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BE800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BF000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BF800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C0000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C0800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C1000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C1800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C2000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C2800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C3000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C3800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C4000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C4800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C5000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C5800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C6000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C6800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C7000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C7800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C8000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C8800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C9000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C9800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CA000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CA800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CB000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CB800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CC000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CC800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CD000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CD800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CE000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CE800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CF000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CF800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D0000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D0800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D1000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D1800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D2000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D2800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D3000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D3800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D4000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D4800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D5000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D5800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D6000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D6800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D7000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D7800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D8000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D8800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D9000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D9800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DA000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DA800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DB000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DB800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DC000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DC800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DD000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DD800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DE000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DE800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DF000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DF800 */
-168, 17,169,170, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E0000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E0800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E1000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E1800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E2000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E2800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E3000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E3800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E4000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E4800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E5000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E5800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E6000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E6800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E7000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E7800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E8000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E8800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E9000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E9800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EA000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EA800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EB000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EB800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EC000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EC800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+ED000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+ED800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EE000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EE800 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EF000 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EF800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F0000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F0800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F1000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F1800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F2000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F2800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F3000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F3800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F4000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F4800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F5000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F5800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F6000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F6800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F7000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F7800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F8000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F8800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F9000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F9800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FA000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FA800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FB000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FB800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FC000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FC800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FD000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FD800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FE000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FE800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FF000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,171, /* U+FF800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+100000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+100800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+101000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+101800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+102000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+102800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+103000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+103800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+104000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+104800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+105000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+105800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+106000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+106800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+107000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+107800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+108000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+108800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+109000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+109800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10A000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10A800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10B000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10B800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10C000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10C800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10D000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10D800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10E000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10E800 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10F000 */
-114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,171, /* U+10F800 */
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,188, 94, /* U+2B000 */
+189, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2B800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2C000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2C800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2D000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2D800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2E000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2E800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2F000 */
+ 94, 94, 94, 94,189, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+2F800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+30000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+30800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+31000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+31800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+32000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+32800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+33000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+33800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+34000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+34800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+35000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+35800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+36000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+36800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+37000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+37800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+38000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+38800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+39000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+39800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3A000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3A800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3B000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3B800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3C000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3C800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3D000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3D800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3E000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3E800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3F000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+3F800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+40000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+40800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+41000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+41800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+42000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+42800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+43000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+43800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+44000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+44800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+45000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+45800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+46000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+46800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+47000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+47800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+48000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+48800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+49000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+49800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4A000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4A800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4B000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4B800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4C000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4C800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4D000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4D800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4E000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4E800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4F000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+4F800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+50000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+50800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+51000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+51800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+52000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+52800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+53000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+53800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+54000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+54800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+55000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+55800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+56000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+56800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+57000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+57800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+58000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+58800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+59000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+59800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5A000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5A800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5B000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5B800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5C000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5C800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5D000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5D800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5E000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5E800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5F000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+5F800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+60000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+60800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+61000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+61800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+62000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+62800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+63000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+63800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+64000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+64800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+65000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+65800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+66000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+66800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+67000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+67800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+68000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+68800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+69000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+69800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6A000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6A800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6B000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6B800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6C000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6C800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6D000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6D800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6E000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6E800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6F000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+6F800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+70000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+70800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+71000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+71800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+72000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+72800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+73000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+73800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+74000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+74800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+75000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+75800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+76000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+76800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+77000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+77800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+78000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+78800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+79000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+79800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7A000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7A800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7B000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7B800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7C000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7C800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7D000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7D800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7E000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7E800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7F000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+7F800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+80000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+80800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+81000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+81800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+82000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+82800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+83000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+83800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+84000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+84800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+85000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+85800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+86000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+86800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+87000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+87800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+88000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+88800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+89000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+89800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8A000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8A800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8B000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8B800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8C000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8C800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8D000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8D800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8E000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8E800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8F000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+8F800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+90000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+90800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+91000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+91800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+92000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+92800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+93000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+93800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+94000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+94800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+95000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+95800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+96000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+96800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+97000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+97800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+98000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+98800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+99000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+99800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9A000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9A800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9B000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9B800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9C000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9C800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9D000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9D800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9E000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9E800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9F000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+9F800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A0000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A0800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A1000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A1800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A2000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A2800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A3000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A3800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A4000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A4800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A5000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A5800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A6000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A6800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A7000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A7800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A8000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A8800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A9000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+A9800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AA000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AA800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AB000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AB800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AC000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AC800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AD000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AD800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AE000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AE800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AF000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+AF800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B0000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B0800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B1000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B1800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B2000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B2800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B3000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B3800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B4000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B4800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B5000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B5800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B6000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B6800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B7000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B7800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B8000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B8800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B9000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+B9800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BA000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BA800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BB000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BB800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BC000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BC800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BD000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BD800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BE000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BE800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BF000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+BF800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C0000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C0800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C1000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C1800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C2000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C2800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C3000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C3800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C4000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C4800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C5000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C5800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C6000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C6800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C7000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C7800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C8000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C8800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C9000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+C9800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CA000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CA800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CB000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CB800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CC000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CC800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CD000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CD800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CE000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CE800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CF000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+CF800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D0000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D0800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D1000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D1800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D2000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D2800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D3000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D3800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D4000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D4800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D5000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D5800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D6000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D6800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D7000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D7800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D8000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D8800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D9000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+D9800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DA000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DA800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DB000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DB800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DC000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DC800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DD000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DD800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DE000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DE800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DF000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+DF800 */
+190, 78,191,192, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E0000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E0800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E1000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E1800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E2000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E2800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E3000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E3800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E4000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E4800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E5000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E5800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E6000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E6800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E7000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E7800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E8000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E8800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E9000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+E9800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EA000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EA800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EB000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EB800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EC000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EC800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+ED000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+ED800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EE000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EE800 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EF000 */
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, /* U+EF800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F0000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F0800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F1000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F1800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F2000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F2800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F3000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F3800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F4000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F4800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F5000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F5800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F6000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F6800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F7000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F7800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F8000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F8800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F9000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+F9800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FA000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FA800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FB000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FB800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FC000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FC800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FD000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FD800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FE000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FE800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+FF000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,193, /* U+FF800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+100000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+100800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+101000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+101800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+102000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+102800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+103000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+103800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+104000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+104800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+105000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+105800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+106000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+106800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+107000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+107800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+108000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+108800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+109000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+109800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10A000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10A800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10B000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10B800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10C000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10C800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10D000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10D800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10E000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10E800 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, /* U+10F000 */
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,193, /* U+10F800 */
};
-const pcre_uint16 _pcre_ucd_stage2[] = { /* 44032 bytes, block = 128 */
+const pcre_uint16 PRIV(ucd_stage2)[] = { /* 49664 bytes, block = 128 */
/* block 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -1114,635 +1163,635 @@
/* block 1 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 3, 3, 3, 3, 13, 13, 10, 13, 14, 15, 6, 16, 13, 10,
- 13, 6, 17, 17, 10, 18, 13, 2, 10, 17, 14, 19, 17, 17, 17, 2,
+ 1, 2, 3, 3, 3, 3, 13, 2, 10, 13, 14, 15, 6, 16, 13, 10,
+ 13, 6, 17, 17, 10, 18, 2, 2, 10, 17, 14, 19, 17, 17, 17, 2,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 14,
+ 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 20,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 12, 12, 20,
+ 12, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 12, 12, 21,
/* block 2 */
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 23, 24, 21, 22, 21, 22, 21, 22, 14, 21, 22, 21, 22, 21, 22, 21,
- 22, 21, 22, 21, 22, 21, 22, 21, 22, 14, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 25, 21, 22, 21, 22, 21, 22, 26,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 24, 25, 22, 23, 22, 23, 22, 23, 20, 22, 23, 22, 23, 22, 23, 22,
+ 23, 22, 23, 22, 23, 22, 23, 22, 23, 20, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 26, 22, 23, 22, 23, 22, 23, 27,
/* block 3 */
- 27, 28, 21, 22, 21, 22, 29, 21, 22, 30, 30, 21, 22, 14, 31, 32,
- 33, 21, 22, 30, 34, 35, 36, 37, 21, 22, 38, 14, 36, 39, 40, 41,
- 21, 22, 21, 22, 21, 22, 42, 21, 22, 42, 14, 14, 21, 22, 42, 21,
- 22, 43, 43, 21, 22, 21, 22, 44, 21, 22, 14, 45, 21, 22, 14, 46,
- 45, 45, 45, 45, 47, 48, 49, 47, 48, 49, 47, 48, 49, 21, 22, 21,
- 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 50, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 14, 47, 48, 49, 21, 22, 51, 52, 21, 22, 21, 22, 21, 22, 21, 22,
+ 28, 29, 22, 23, 22, 23, 30, 22, 23, 31, 31, 22, 23, 20, 32, 33,
+ 34, 22, 23, 31, 35, 36, 37, 38, 22, 23, 39, 20, 37, 40, 41, 42,
+ 22, 23, 22, 23, 22, 23, 43, 22, 23, 43, 20, 20, 22, 23, 43, 22,
+ 23, 44, 44, 22, 23, 22, 23, 45, 22, 23, 20, 14, 22, 23, 20, 46,
+ 14, 14, 14, 14, 47, 48, 49, 47, 48, 49, 47, 48, 49, 22, 23, 22,
+ 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 50, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 20, 47, 48, 49, 22, 23, 51, 52, 22, 23, 22, 23, 22, 23, 22, 23,
/* block 4 */
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 53, 14, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 14, 14, 14, 14, 14, 14, 54, 21, 22, 55, 56, 57,
- 57, 21, 22, 58, 59, 60, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 61, 62, 63, 64, 65, 14, 66, 66, 14, 67, 14, 68, 14, 14, 14, 14,
- 66, 14, 14, 69, 14, 14, 14, 14, 70, 71, 14, 72, 14, 14, 14, 71,
- 14, 73, 74, 14, 14, 75, 14, 14, 14, 14, 14, 14, 14, 76, 14, 14,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 53, 20, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 20, 20, 20, 20, 20, 20, 54, 22, 23, 55, 56, 57,
+ 57, 22, 23, 58, 59, 60, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 61, 62, 63, 64, 65, 20, 66, 66, 20, 67, 20, 68, 20, 20, 20, 20,
+ 66, 20, 20, 69, 20, 70, 71, 20, 72, 73, 20, 74, 20, 20, 20, 73,
+ 20, 75, 76, 20, 20, 77, 20, 20, 20, 20, 20, 20, 20, 78, 20, 20,
/* block 5 */
- 77, 14, 14, 77, 14, 14, 14, 14, 77, 78, 79, 79, 80, 14, 14, 14,
- 14, 14, 81, 14, 45, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 10, 10, 10, 10, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 82, 82, 82, 82, 82, 10, 10, 10, 10, 10, 10, 10, 83, 10, 83, 10,
+ 79, 20, 20, 79, 20, 20, 20, 20, 79, 80, 81, 81, 82, 20, 20, 20,
+ 20, 20, 83, 20, 14, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 10, 10, 10, 10, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 84, 84, 84, 84, 84, 10, 10, 10, 10, 10, 86, 86, 85, 10, 85, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
/* block 6 */
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 85, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 86, 87, 86, 87, 83, 88, 86, 87, 89, 89, 90, 91, 91, 91, 2, 89,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 89, 90, 89, 90, 85, 91, 89, 90, 92, 92, 93, 94, 94, 94, 2, 92,
/* block 7 */
- 89, 89, 89, 89, 88, 10, 92, 2, 93, 93, 93, 89, 94, 89, 95, 95,
- 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
- 97, 97, 89, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 99, 99, 99,
- 96,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-100,100,101,100,100,100,100,100,100,100,100,100,102,103,103,104,
-105,106,107,107,107,108,109,110, 86, 87, 86, 87, 86, 87, 86, 87,
- 86, 87,111,112,111,112,111,112,111,112,111,112,111,112,111,112,
-113,114,115, 96,116,117,118, 86, 87,119, 86, 87, 96,120,120,120,
+ 92, 92, 92, 92, 91, 10, 95, 2, 96, 96, 96, 92, 97, 92, 98, 98,
+ 99,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100, 92,100,100,100,100,100,100,100,100,100,101,102,102,102,
+ 99,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,104,103,103,103,103,103,103,103,103,103,105,106,106,107,
+108,109,110,110,110,111,112,113, 89, 90, 89, 90, 89, 90, 89, 90,
+ 89, 90,114,115,114,115,114,115,114,115,114,115,114,115,114,115,
+116,117,118, 99,119,120,121, 89, 90,122, 89, 90, 99,123,123,123,
/* block 8 */
-121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
-122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
-122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
/* block 9 */
-125,126,127,128,128, 84, 84,128,129,129,125,126,125,126,125,126,
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
-130,125,126,125,126,125,126,125,126,125,126,125,126,125,126,131,
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
+128,129,130,131,131, 87, 87,131,132,132,128,129,128,129,128,129,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
+133,128,129,128,129,128,129,128,129,128,129,128,129,128,129,134,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
/* block 10 */
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
-125,126,125,126,125,126, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
-132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
-132,132,132,132,132,132,132, 89, 89,133,134,134,134,134,134,134,
- 89,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
+128,129,128,129,128,129,128,129, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135, 92, 92,136,137,137,137,137,137,137,
+ 92,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
/* block 11 */
-135,135,135,135,135,135,135,136, 89, 2,137, 89, 89, 89, 89, 89,
- 89,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
-138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
-138,138,138,138,138,138,138,138,138,138,138,138,138,138,139,138,
-140,138,138,140,138,138,140,138, 89, 89, 89, 89, 89, 89, 89, 89,
-141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
-141,141,141,141,141,141,141,141,141,141,141, 89, 89, 89, 89, 89,
-141,141,141,140,140, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+138,138,138,138,138,138,138,139, 92, 2,140, 92, 92, 92, 92,141,
+ 92,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,143,142,
+144,142,142,144,142,142,144,142, 92, 92, 92, 92, 92, 92, 92, 92,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145, 92, 92, 92, 92, 92,
+145,145,145,144,144, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 12 */
- 16, 16, 16, 16, 89, 89,142,142,142,143,143,144, 2,143,145,145,
-146,146,146,146,146,146,146,146,146,146,146, 2, 89, 89,143, 2,
- 89,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
- 83,147,147,147,147,147,147,147,147,147,147, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84,146,146,146,146,146,146,146,146,146, 89,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,143,143,143,143,147,147,
- 84,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+146,146,146,146,146, 92,147,147,147,148,148,149, 2,148,150,150,
+151,151,151,151,151,151,151,151,151,151,151, 2, 92, 92,148, 2,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+ 85,152,152,152,152,152,152,152,152,152,152, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87,151,151,151,151,151,151,151,151,151, 87,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,148,148,148,148,152,152,
+ 87,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
/* block 13 */
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,143,147,146,146,146,146,146,146,146, 16,148,146,
-146,146,146,146,146,149,149,146,146,145,146,146,146,146,147,147,
-150,150,150,150,150,150,150,150,150,150,147,147,147,145,145,147,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,148,152,151,151,151,151,151,151,151, 16,150,151,
+151,151,151,151,151,153,153,151,151,150,151,151,151,151,152,152,
+154,154,154,154,154,154,154,154,154,154,152,152,152,150,150,152,
/* block 14 */
-151,151,151,151,151,151,151,151,151,151,151,151,151,151, 89,152,
-153,154,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
-153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
-154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
-154,154,154,154,154,154,154,154,154,154,154, 89, 89,153,153,153,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155, 92,156,
+157,158,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158, 92, 92,157,157,157,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
/* block 15 */
-155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
-155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
-155,155,155,155,155,155,156,156,156,156,156,156,156,156,156,156,
-156,155, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-157,157,157,157,157,157,157,157,157,157,158,158,158,158,158,158,
-158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
-158,158,158,158,158,158,158,158,158,158,158,159,159,159,159,159,
-159,159,159,159,160,160,161,162,162,162,160, 89, 89, 89, 89, 89,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,160,160,160,160,160,160,160,160,160,160,
+160,159, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+161,161,161,161,161,161,161,161,161,161,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,163,163,163,163,163,
+163,163,163,163,164,164,165,166,166,166,164, 92, 92, 92, 92, 92,
/* block 16 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-163,163,163,163,163,163,164,164,164,164,165,164,164,164,164,164,
-164,164,164,164,165,164,164,164,165,164,164,164,164,164, 89, 89,
-166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,168,168,168,168,169,168,168,168,168,168,
+168,168,168,168,169,168,168,168,169,168,168,168,168,168, 92, 92,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, 92,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,172,172,172, 92, 92,173, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 17 */
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+152, 92,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, 92,
/* block 18 */
-167,167,167,168,169,169,169,169,169,169,169,169,169,169,169,169,
-169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
-169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
-169,169,169,169,169,169,169,169,169,169, 89, 89,167,169,168,168,
-168,167,167,167,167,167,167,167,167,168,168,168,168,167,168, 89,
-169, 84, 84,167,167,167, 89, 89,169,169,169,169,169,169,169,169,
-169,169,167,167, 2, 2,170,170,170,170,170,170,170,170,170,170,
- 2,171,169, 89, 89, 89, 89, 89, 89,169,169,169,169,169,169,169,
+174,174,174,175,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,174,175,174,176,175,175,
+175,174,174,174,174,174,174,174,174,175,175,175,175,174,175,175,
+176, 87, 87,174,174,174,174,174,176,176,176,176,176,176,176,176,
+176,176,174,174, 2, 2,177,177,177,177,177,177,177,177,177,177,
+178,179,176,176,176,176,176,176, 92,176,176,176,176,176,176,176,
/* block 19 */
- 89,172,173,173, 89,174,174,174,174,174,174,174,174, 89, 89,174,
-174, 89, 89,174,174,174,174,174,174,174,174,174,174,174,174,174,
-174,174,174,174,174,174,174,174,174, 89,174,174,174,174,174,174,
-174, 89,174, 89, 89, 89,174,174,174,174, 89, 89,172,174,173,173,
-173,172,172,172,172, 89, 89,173,173, 89, 89,173,173,172,174, 89,
- 89, 89, 89, 89, 89, 89, 89,173, 89, 89, 89, 89,174,174, 89,174,
-174,174,172,172, 89, 89,175,175,175,175,175,175,175,175,175,175,
-174,174,176,176,177,177,177,177,177,177,178,176, 89, 89, 89, 89,
+ 92,180,181,181, 92,182,182,182,182,182,182,182,182, 92, 92,182,
+182, 92, 92,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182, 92,182,182,182,182,182,182,
+182, 92,182, 92, 92, 92,182,182,182,182, 92, 92,180,182,181,181,
+181,180,180,180,180, 92, 92,181,181, 92, 92,181,181,180,182, 92,
+ 92, 92, 92, 92, 92, 92, 92,181, 92, 92, 92, 92,182,182, 92,182,
+182,182,180,180, 92, 92,183,183,183,183,183,183,183,183,183,183,
+182,182,184,184,185,185,185,185,185,185,186,184, 92, 92, 92, 92,
/* block 20 */
- 89,179,179,180, 89,181,181,181,181,181,181, 89, 89, 89, 89,181,
-181, 89, 89,181,181,181,181,181,181,181,181,181,181,181,181,181,
-181,181,181,181,181,181,181,181,181, 89,181,181,181,181,181,181,
-181, 89,181,181, 89,181,181, 89,181,181, 89, 89,179, 89,180,180,
-180,179,179, 89, 89, 89, 89,179,179, 89, 89,179,179,179, 89, 89,
- 89,179, 89, 89, 89, 89, 89, 89, 89,181,181,181,181, 89,181, 89,
- 89, 89, 89, 89, 89, 89,182,182,182,182,182,182,182,182,182,182,
-179,179,181,181,181,179, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 92,187,187,188, 92,189,189,189,189,189,189, 92, 92, 92, 92,189,
+189, 92, 92,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189, 92,189,189,189,189,189,189,
+189, 92,189,189, 92,189,189, 92,189,189, 92, 92,187, 92,188,188,
+188,187,187, 92, 92, 92, 92,187,187, 92, 92,187,187,187, 92, 92,
+ 92,187, 92, 92, 92, 92, 92, 92, 92,189,189,189,189, 92,189, 92,
+ 92, 92, 92, 92, 92, 92,190,190,190,190,190,190,190,190,190,190,
+187,187,189,189,189,187, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 21 */
- 89,183,183,184, 89,185,185,185,185,185,185,185,185,185, 89,185,
-185,185, 89,185,185,185,185,185,185,185,185,185,185,185,185,185,
-185,185,185,185,185,185,185,185,185, 89,185,185,185,185,185,185,
-185, 89,185,185, 89,185,185,185,185,185, 89, 89,183,185,184,184,
-184,183,183,183,183,183, 89,183,183,184, 89,184,184,183, 89, 89,
-185, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-185,185,183,183, 89, 89,186,186,186,186,186,186,186,186,186,186,
- 89,187, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 92,191,191,192, 92,193,193,193,193,193,193,193,193,193, 92,193,
+193,193, 92,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193, 92,193,193,193,193,193,193,
+193, 92,193,193, 92,193,193,193,193,193, 92, 92,191,193,192,192,
+192,191,191,191,191,191, 92,191,191,192, 92,192,192,191, 92, 92,
+193, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+193,193,191,191, 92, 92,194,194,194,194,194,194,194,194,194,194,
+195,196, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 22 */
- 89,188,189,189, 89,190,190,190,190,190,190,190,190, 89, 89,190,
-190, 89, 89,190,190,190,190,190,190,190,190,190,190,190,190,190,
-190,190,190,190,190,190,190,190,190, 89,190,190,190,190,190,190,
-190, 89,190,190, 89,190,190,190,190,190, 89, 89,188,190,189,188,
-189,188,188,188,188, 89, 89,189,189, 89, 89,189,189,188, 89, 89,
- 89, 89, 89, 89, 89, 89,188,189, 89, 89, 89, 89,190,190, 89,190,
-190,190,188,188, 89, 89,191,191,191,191,191,191,191,191,191,191,
-192,190, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 92,197,198,198, 92,199,199,199,199,199,199,199,199, 92, 92,199,
+199, 92, 92,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199, 92,199,199,199,199,199,199,
+199, 92,199,199, 92,199,199,199,199,199, 92, 92,197,199,198,197,
+198,197,197,197,197, 92, 92,198,198, 92, 92,198,198,197, 92, 92,
+ 92, 92, 92, 92, 92, 92,197,198, 92, 92, 92, 92,199,199, 92,199,
+199,199,197,197, 92, 92,200,200,200,200,200,200,200,200,200,200,
+201,199,202,202,202,202,202,202, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 23 */
- 89, 89,193,194, 89,194,194,194,194,194,194, 89, 89, 89,194,194,
-194, 89,194,194,194,194, 89, 89, 89,194,194, 89,194, 89,194,194,
- 89, 89, 89,194,194, 89, 89, 89,194,194,194, 89, 89, 89,194,194,
-194,194,194,194,194,194,194,194,194,194, 89, 89, 89, 89,195,195,
-193,195,195, 89, 89, 89,195,195,195, 89,195,195,195,193, 89, 89,
-194, 89, 89, 89, 89, 89, 89,195, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89,196,196,196,196,196,196,196,196,196,196,
-197,197,197,198,198,198,198,198,198,199,198, 89, 89, 89, 89, 89,
+ 92, 92,203,204, 92,204,204,204,204,204,204, 92, 92, 92,204,204,
+204, 92,204,204,204,204, 92, 92, 92,204,204, 92,204, 92,204,204,
+ 92, 92, 92,204,204, 92, 92, 92,204,204,204, 92, 92, 92,204,204,
+204,204,204,204,204,204,204,204,204,204, 92, 92, 92, 92,205,205,
+203,205,205, 92, 92, 92,205,205,205, 92,205,205,205,203, 92, 92,
+204, 92, 92, 92, 92, 92, 92,205, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92,206,206,206,206,206,206,206,206,206,206,
+207,207,207,208,208,208,208,208,208,209,208, 92, 92, 92, 92, 92,
/* block 24 */
- 89,200,200,200, 89,201,201,201,201,201,201,201,201, 89,201,201,
-201, 89,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
-201,201,201,201,201,201,201,201,201, 89,201,201,201,201,201,201,
-201,201,201,201, 89,201,201,201,201,201, 89, 89, 89,201,202,202,
-202,200,200,200,200, 89,202,202,202, 89,202,202,202,202, 89, 89,
- 89, 89, 89, 89, 89,202,202, 89,201,201, 89, 89, 89, 89, 89, 89,
-201,201,202,202, 89, 89,203,203,203,203,203,203,203,203,203,203,
- 89, 89, 89, 89, 89, 89, 89, 89,204,204,204,204,204,204,204,205,
+ 92,210,210,210, 92,211,211,211,211,211,211,211,211, 92,211,211,
+211, 92,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211, 92,211,211,211,211,211,211,
+211,211,211,211, 92,211,211,211,211,211, 92, 92, 92,211,212,212,
+212,210,210,210,210, 92,212,212,212, 92,212,212,212,212, 92, 92,
+ 92, 92, 92, 92, 92,212,212, 92,211,211, 92, 92, 92, 92, 92, 92,
+211,211,212,212, 92, 92,213,213,213,213,213,213,213,213,213,213,
+ 92, 92, 92, 92, 92, 92, 92, 92,214,214,214,214,214,214,214,215,
/* block 25 */
- 89, 89,206,206, 89,207,207,207,207,207,207,207,207, 89,207,207,
-207, 89,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
-207,207,207,207,207,207,207,207,207, 89,207,207,207,207,207,207,
-207,207,207,207, 89,207,207,207,207,207, 89, 89,208,207,206,208,
-206,206,206,206,206, 89,208,206,206, 89,206,206,208,208, 89, 89,
- 89, 89, 89, 89, 89,206,206, 89, 89, 89, 89, 89, 89, 89,207, 89,
-207,207,208,208, 89, 89,209,209,209,209,209,209,209,209,209,209,
- 89, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 92, 92,216,216, 92,217,217,217,217,217,217,217,217, 92,217,217,
+217, 92,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217, 92,217,217,217,217,217,217,
+217,217,217,217, 92,217,217,217,217,217, 92, 92,218,217,216,218,
+216,216,216,216,216, 92,218,216,216, 92,216,216,218,218, 92, 92,
+ 92, 92, 92, 92, 92,216,216, 92, 92, 92, 92, 92, 92, 92,217, 92,
+217,217,218,218, 92, 92,219,219,219,219,219,219,219,219,219,219,
+ 92,217,217, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 26 */
- 89, 89,210,210, 89,211,211,211,211,211,211,211,211, 89,211,211,
-211, 89,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
-211,211,211,211,211,211,211,211,211, 89,211,211,211,211,211,211,
-211,211,211,211,211,211,211,211,211,211, 89, 89, 89,211,210,210,
-210,212,212,212,212, 89,210,210,210, 89,210,210,210,212, 89, 89,
- 89, 89, 89, 89, 89, 89, 89,210, 89, 89, 89, 89, 89, 89, 89, 89,
-211,211,212,212, 89, 89,213,213,213,213,213,213,213,213,213,213,
-214,214,214,214,214,214, 89, 89, 89,215,211,211,211,211,211,211,
+ 92, 92,220,220, 92,221,221,221,221,221,221,221,221, 92,221,221,
+221, 92,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221, 92, 92,221,220,220,
+220,222,222,222,222, 92,220,220,220, 92,220,220,220,222,221, 92,
+ 92, 92, 92, 92, 92, 92, 92,220, 92, 92, 92, 92, 92, 92, 92, 92,
+221,221,222,222, 92, 92,223,223,223,223,223,223,223,223,223,223,
+224,224,224,224,224,224, 92, 92, 92,225,221,221,221,221,221,221,
/* block 27 */
- 89, 89,216,216, 89,217,217,217,217,217,217,217,217,217,217,217,
-217,217,217,217,217,217,217, 89, 89, 89,217,217,217,217,217,217,
-217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
-217,217, 89,217,217,217,217,217,217,217,217,217, 89,217, 89, 89,
-217,217,217,217,217,217,217, 89, 89, 89,218, 89, 89, 89, 89,216,
-216,216,218,218,218, 89,218, 89,216,216,216,216,216,216,216,216,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89,216,216,219, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 92, 92,226,226, 92,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227, 92, 92, 92,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227, 92,227,227,227,227,227,227,227,227,227, 92,227, 92, 92,
+227,227,227,227,227,227,227, 92, 92, 92,228, 92, 92, 92, 92,226,
+226,226,228,228,228, 92,228, 92,226,226,226,226,226,226,226,226,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92,226,226,229, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 28 */
- 89,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
-220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
-220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
-220,221,220,220,221,221,221,221,221,221,221, 89, 89, 89, 89, 3,
-220,220,220,220,220,220,222,221,221,221,221,221,221,221,221,223,
-224,224,224,224,224,224,224,224,224,224,223,223, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 92,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,231,230,230,231,231,231,231,231,231,231, 92, 92, 92, 92, 3,
+230,230,230,230,230,230,232,231,231,231,231,231,231,231,231,233,
+234,234,234,234,234,234,234,234,234,234,233,233, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 29 */
- 89,225,225, 89,225, 89, 89,225,225, 89,225, 89, 89,225, 89, 89,
- 89, 89, 89, 89,225,225,225,225, 89,225,225,225,225,225,225,225,
- 89,225,225,225, 89,225, 89,225, 89, 89,225,225, 89,225,225,225,
-225,226,225,225,226,226,226,226,226,226, 89,226,226,225, 89, 89,
-225,225,225,225,225, 89,227, 89,226,226,226,226,226,226, 89, 89,
-228,228,228,228,228,228,228,228,228,228, 89, 89,225,225, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 92,235,235, 92,235, 92, 92,235,235, 92,235, 92, 92,235, 92, 92,
+ 92, 92, 92, 92,235,235,235,235, 92,235,235,235,235,235,235,235,
+ 92,235,235,235, 92,235, 92,235, 92, 92,235,235, 92,235,235,235,
+235,236,235,235,236,236,236,236,236,236, 92,236,236,235, 92, 92,
+235,235,235,235,235, 92,237, 92,236,236,236,236,236,236, 92, 92,
+238,238,238,238,238,238,238,238,238,238, 92, 92,235,235,235,235,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 30 */
-229,230,230,230,231,231,231,231,231,231,231,231,231,231,231,231,
-231,231,231,230,230,230,230,230,232,232,230,230,230,230,230,230,
-233,233,233,233,233,233,233,233,233,233,234,234,234,234,234,234,
-234,234,234,234,230,232,230,232,230,232,235,236,235,236,237,237,
-229,229,229,229,229,229,229,229, 89,229,229,229,229,229,229,229,
-229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
-229,229,229,229,229,229,229,229,229,229,229,229,229, 89, 89, 89,
- 89,232,232,232,232,232,232,232,232,232,232,232,232,232,232,237,
+239,240,240,240,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,240,241,240,240,240,242,242,240,240,240,240,240,240,
+243,243,243,243,243,243,243,243,243,243,244,244,244,244,244,244,
+244,244,244,244,240,242,240,242,240,242,245,246,245,246,247,247,
+239,239,239,239,239,239,239,239, 92,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239, 92, 92, 92,
+ 92,242,242,242,242,242,242,242,242,242,242,242,242,242,242,247,
/* block 31 */
-232,232,232,232,232,231,232,232,229,229,229,229, 89, 89, 89, 89,
-232,232,232,232,232,232,232,232, 89,232,232,232,232,232,232,232,
-232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
-232,232,232,232,232,232,232,232,232,232,232,232,232, 89,230,230,
-230,230,230,230,230,230,232,230,230,230,230,230,230, 89,230,230,
-231,231,231,231,231, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+242,242,242,242,242,241,242,242,239,239,239,239,239,242,242,242,
+242,242,242,242,242,242,242,242, 92,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242, 92,240,240,
+240,240,240,240,240,240,242,240,240,240,240,240,240, 92,240,240,
+241,241,241,241,241, 13, 13, 13, 13,241,241, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 32 */
-238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
-238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
-238,238,238,238,238,238,238,238,238,238,238,239,239,240,240,240,
-240,239,240,240,240,240,240,240,239,240,240,239,239,240,240,238,
-241,241,241,241,241,241,241,241,241,241,242,242,242,242,242,242,
-238,238,238,238,238,238,239,239,240,240,238,238,238,238,240,240,
-240,238,239,239,239,238,238,239,239,239,239,239,239,239,238,238,
-238,240,240,240,240,238,238,238,238,238,238,238,238,238,238,238,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,249,249,250,250,250,
+250,249,250,250,250,250,250,250,249,250,250,249,249,250,250,248,
+251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,252,
+248,248,248,248,248,248,249,249,250,250,248,248,248,248,250,250,
+250,248,249,249,249,248,248,249,249,249,249,249,249,249,248,248,
+248,250,250,250,250,248,248,248,248,248,248,248,248,248,248,248,
/* block 33 */
-238,238,240,239,239,240,240,239,239,239,239,239,239,240,238,239,
-241,241,241,241,241,241,241,241,241,241,239,239,239,240,243,243,
-244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
-244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
-244,244,244,244,244,244, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
-245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
-245,245,245,245,245,245,245,245,245,245,245, 2,246, 89, 89, 89,
+248,248,250,249,249,250,250,249,249,249,249,249,249,250,248,249,
+251,251,251,251,251,251,251,251,251,251,249,249,249,250,253,253,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254, 92,254, 92, 92, 92, 92, 92,254, 92, 92,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255, 2,256,255,255,255,
/* block 34 */
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
/* block 35 */
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248, 89,248,248,248,248, 89, 89,
-248,248,248,248,248,248,248, 89,248, 89,248,248,248,248, 89, 89,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258, 92,258,258,258,258, 92, 92,
+258,258,258,258,258,258,258, 92,258, 92,258,258,258,258, 92, 92,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
/* block 36 */
-248,248,248,248,248,248,248,248,248, 89,248,248,248,248, 89, 89,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248, 89,248,248,248,248, 89, 89,248,248,248,248,248,248,248, 89,
-248, 89,248,248,248,248, 89, 89,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+258,258,258,258,258,258,258,258,258, 92,258,258,258,258, 92, 92,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258, 92,
+258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
/* block 37 */
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248, 89,248,248,248,248, 89, 89,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,248,248, 89, 89, 89, 89,249,
-250,251,251,251,251,251,251,251,251,252,252,252,252,252,252,252,
-252,252,252,252,252,252,252,252,252,252,252,252,252, 89, 89, 89,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258, 92,258,258,258,258, 92, 92,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258, 92, 92,259,259,259,
+260,260,260,260,260,260,260,260,260,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261, 92, 92, 92,
/* block 38 */
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-250,250,250,250,250,250,250,250,250,250, 89, 89, 89, 89, 89, 89,
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
-253,253,253,253,253, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+262,262,262,262,262,262,262,262,262,262, 92, 92, 92, 92, 92, 92,
+263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,
+263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,
+263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,
+263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,
+263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,
+263,263,263,263,263, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 39 */
-254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+264,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
/* block 40 */
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
/* block 41 */
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,256,256,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,266,266,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
/* block 42 */
-257,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
-258,258,258,258,258,258,258,258,258,258,258,259,260, 89, 89, 89,
-261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
-261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
-261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
-261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
-261,261,261,261,261,261,261,261,261,261,261, 2, 2, 2,262,262,
-262, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+267,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,
+268,268,268,268,268,268,268,268,268,268,268,269,270, 92, 92, 92,
+271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,
+271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,
+271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,
+271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,
+271,271,271,271,271,271,271,271,271,271,271, 2, 2, 2,272,272,
+272, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 43 */
-263,263,263,263,263,263,263,263,263,263,263,263,263, 89,263,263,
-263,263,264,264,264, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
-265,265,266,266,266, 2, 2, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,
-267,267,268,268, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-269,269,269,269,269,269,269,269,269,269,269,269,269, 89,269,269,
-269, 89,270,270, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+273,273,273,273,273,273,273,273,273,273,273,273,273, 92,273,273,
+273,273,274,274,274, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,
+275,275,276,276,276, 2, 2, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,
+277,277,278,278, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+279,279,279,279,279,279,279,279,279,279,279,279,279, 92,279,279,
+279, 92,280,280, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 44 */
-271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,
-271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,
-271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,
-271,271,271,271,272,272,273,274,274,274,274,274,274,274,273,273,
-273,273,273,273,273,273,274,273,273,274,274,274,274,274,274,274,
-274,274,274,274,275,275,275,276,275,275,275,277,271,274, 89, 89,
-278,278,278,278,278,278,278,278,278,278, 89, 89, 89, 89, 89, 89,
-279,279,279,279,279,279,279,279,279,279, 89, 89, 89, 89, 89, 89,
+281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,
+281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,
+281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,
+281,281,281,281,282,282,283,282,282,282,282,282,282,282,283,283,
+283,283,283,283,283,283,282,283,283,282,282,282,282,282,282,282,
+282,282,282,282,284,284,284,285,284,284,284,286,281,282, 92, 92,
+287,287,287,287,287,287,287,287,287,287, 92, 92, 92, 92, 92, 92,
+288,288,288,288,288,288,288,288,288,288, 92, 92, 92, 92, 92, 92,
/* block 45 */
-280,280, 2, 2,280, 2,281,280,280,280,280,282,282,282,283, 89,
-284,284,284,284,284,284,284,284,284,284, 89, 89, 89, 89, 89, 89,
-285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
-285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
-285,285,285,286,285,285,285,285,285,285,285,285,285,285,285,285,
-285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
-285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
-285,285,285,285,285,285,285,285, 89, 89, 89, 89, 89, 89, 89, 89,
+289,289, 2, 2,289, 2,290,289,289,289,289,291,291,291,292, 92,
+293,293,293,293,293,293,293,293,293,293, 92, 92, 92, 92, 92, 92,
+294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,
+294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,
+294,294,294,295,294,294,294,294,294,294,294,294,294,294,294,294,
+294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,
+294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,
+294,294,294,294,294,294,294,294, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 46 */
-285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
-285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,285,
-285,285,285,285,285,285,285,285,285,282,285, 89, 89, 89, 89, 89,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-255,255,255,255,255,255, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,
+294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,
+294,294,294,294,294,294,294,294,294,291,294, 92, 92, 92, 92, 92,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,265,
+265,265,265,265,265,265, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 47 */
-287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,287,
-287,287,287,287,287,287,287,287,287,287,287,287,287, 89, 89, 89,
-288,288,288,289,289,289,289,288,288,289,289,289, 89, 89, 89, 89,
-289,289,288,289,289,289,289,289,289,288,288,288, 89, 89, 89, 89,
-290, 89, 89, 89,291,291,292,292,292,292,292,292,292,292,292,292,
-293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,
-293,293,293,293,293,293,293,293,293,293,293,293,293,293, 89, 89,
-293,293,293,293,293, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,
+296,296,296,296,296,296,296,296,296,296,296,296,296, 92, 92, 92,
+297,297,297,298,298,298,298,297,297,298,298,298, 92, 92, 92, 92,
+298,298,297,298,298,298,298,298,298,297,297,297, 92, 92, 92, 92,
+299, 92, 92, 92,300,300,301,301,301,301,301,301,301,301,301,301,
+302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,
+302,302,302,302,302,302,302,302,302,302,302,302,302,302, 92, 92,
+302,302,302,302,302, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 48 */
-294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,
-294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,294,
-294,294,294,294,294,294,294,294,294,294,294,294, 89, 89, 89, 89,
-295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,
-295,294,294,294,294,294,294,294,295,295, 89, 89, 89, 89, 89, 89,
-296,296,296,296,296,296,296,296,296,296,296, 89, 89, 89,297,297,
-298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,
-298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,298,
-
-/* block 49 */
-299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,
-299,299,299,299,299,299,299,300,300,301,301,301, 89, 89,302,302,
-303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,
303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,
303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,
-303,303,303,303,303,304,305,304,305,305,305,305,305,305,305, 89,
-305,304,305,304,304,305,305,305,305,305,305,305,305,304,304,304,
-304,304,304,305,305,305,305,305,305,305,305,305,305, 89, 89,305,
+303,303,303,303,303,303,303,303,303,303,303,303, 92, 92, 92, 92,
+304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,304,
+304,303,303,303,303,303,303,303,304,304, 92, 92, 92, 92, 92, 92,
+305,305,305,305,305,305,305,305,305,305,306, 92, 92, 92,307,307,
+308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
+308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
+
+/* block 49 */
+309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,309,
+309,309,309,309,309,309,309,310,310,311,311,311, 92, 92,312,312,
+313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
+313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
+313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
+313,313,313,313,313,314,315,314,315,315,315,315,315,315,315, 92,
+315,314,315,314,314,315,315,315,315,315,315,315,315,314,314,314,
+314,314,314,315,315,315,315,315,315,315,315,315,315, 92, 92,315,
/* block 50 */
-306,306,306,306,306,306,306,306,306,306, 89, 89, 89, 89, 89, 89,
-306,306,306,306,306,306,306,306,306,306, 89, 89, 89, 89, 89, 89,
-307,307,307,307,307,307,307,308,307,307,307,307,307,307, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+316,316,316,316,316,316,316,316,316,316, 92, 92, 92, 92, 92, 92,
+316,316,316,316,316,316,316,316,316,316, 92, 92, 92, 92, 92, 92,
+317,317,317,317,317,317,317,318,317,317,317,317,317,317, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 51 */
-309,309,309,309,310,311,311,311,311,311,311,311,311,311,311,311,
-311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,
-311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,
-311,311,311,311,309,310,309,309,309,309,309,310,309,310,310,310,
-310,310,309,310,310,311,311,311,311,311,311,311, 89, 89, 89, 89,
-312,312,312,312,312,312,312,312,312,312,313,313,313,313,313,313,
-313,314,314,314,314,314,314,314,314,314,314,309,309,309,309,309,
-309,309,309,309,314,314,314,314,314,314,314,314,314, 89, 89, 89,
+319,319,319,319,320,321,321,321,321,321,321,321,321,321,321,321,
+321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,
+321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,
+321,321,321,321,319,320,319,319,319,319,319,320,319,320,320,320,
+320,320,319,320,320,321,321,321,321,321,321,321, 92, 92, 92, 92,
+322,322,322,322,322,322,322,322,322,322,323,323,323,323,323,323,
+323,324,324,324,324,324,324,324,324,324,324,319,319,319,319,319,
+319,319,319,319,324,324,324,324,324,324,324,324,324, 92, 92, 92,
/* block 52 */
-315,315,316,317,317,317,317,317,317,317,317,317,317,317,317,317,
-317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,317,
-317,316,315,315,315,315,316,316,315,315,316, 89, 89, 89,317,317,
-318,318,318,318,318,318,318,318,318,318, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+325,325,326,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
+327,326,325,325,325,325,326,326,325,325,326,325,326,326,327,327,
+328,328,328,328,328,328,328,328,328,328,327,327,327,327,327,327,
+329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,
+329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,329,
+329,329,329,329,329,329,330,331,330,330,331,331,331,330,331,330,
+330,330,331,331, 92, 92, 92, 92, 92, 92, 92, 92,332,332,332,332,
/* block 53 */
-319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,
-319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,319,
-319,319,319,319,320,320,320,320,320,320,320,320,321,321,321,321,
-321,321,321,321,320,320,321,321, 89, 89, 89,322,322,322,322,322,
-323,323,323,323,323,323,323,323,323,323, 89, 89, 89,319,319,319,
-324,324,324,324,324,324,324,324,324,324,325,325,325,325,325,325,
-325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,
-325,325,325,325,325,325,325,325,326,326,326,326,326,326,327,327,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,333,
+333,333,333,333,334,334,334,334,334,334,334,334,335,335,335,335,
+335,335,335,335,334,334,335,335, 92, 92, 92,336,336,336,336,336,
+337,337,337,337,337,337,337,337,337,337, 92, 92, 92,333,333,333,
+338,338,338,338,338,338,338,338,338,338,339,339,339,339,339,339,
+339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,
+339,339,339,339,339,339,339,339,340,340,340,340,340,340,341,341,
/* block 54 */
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 84, 84, 84, 2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84,328, 84, 84, 84, 84, 84, 84, 84,329,329,329,329, 84,329,329,
-329,329,328, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+342,342,342,342,342,342,342,342, 92, 92, 92, 92, 92, 92, 92, 92,
+ 87, 87, 87, 2, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87,343, 87, 87, 87, 87, 87, 87, 87,344,344,344,344, 87,344,344,
+344,344,343,343, 87,344,344, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 55 */
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 96, 96, 96, 96, 96,330, 82, 82, 82, 82,
- 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
- 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
- 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 90, 90, 90,
- 90, 90, 14, 14, 14, 14, 96, 96, 96, 96, 96, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14,331,332, 14, 14, 14,333, 14, 14,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 99, 99, 99, 99, 99,345, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 93, 93, 93,
+ 93, 93, 84, 84, 84, 84, 93, 93, 93, 93, 93, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,346,347, 20, 20, 20,348, 20, 20,
/* block 56 */
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 82, 82, 82, 82, 82,
- 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
- 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 90,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 84, 84, 84,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 93,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 87, 87, 87, 87,
/* block 57 */
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
/* block 58 */
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 14, 14, 14, 14, 14,334, 14, 14,335, 14,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 20, 20, 20, 20, 20,349, 20, 20,350, 20,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
/* block 59 */
-336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337,
-336,336,336,336,336,336, 89, 89,337,337,337,337,337,337, 89, 89,
-336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337,
-336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337,
-336,336,336,336,336,336, 89, 89,337,337,337,337,337,337, 89, 89,
- 96,336, 96,336, 96,336, 96,336, 89,337, 89,337, 89,337, 89,337,
-336,336,336,336,336,336,336,336,337,337,337,337,337,337,337,337,
-338,338,339,339,339,339,340,340,341,341,342,342,343,343, 89, 89,
+351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352,
+351,351,351,351,351,351, 92, 92,352,352,352,352,352,352, 92, 92,
+351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352,
+351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352,
+351,351,351,351,351,351, 92, 92,352,352,352,352,352,352, 92, 92,
+ 99,351, 99,351, 99,351, 99,351, 92,352, 92,352, 92,352, 92,352,
+351,351,351,351,351,351,351,351,352,352,352,352,352,352,352,352,
+353,353,354,354,354,354,355,355,356,356,357,357,358,358, 92, 92,
/* block 60 */
-336,336,336,336,336,336,336,336,344,344,344,344,344,344,344,344,
-336,336,336,336,336,336,336,336,344,344,344,344,344,344,344,344,
-336,336,336,336,336,336,336,336,344,344,344,344,344,344,344,344,
-336,336, 96,345, 96, 89, 96, 96,337,337,346,346,347, 88,348, 88,
- 88, 88, 96,345, 96, 89, 96, 96,349,349,349,349,347, 88, 88, 88,
-336,336, 96, 96, 89, 89, 96, 96,337,337,350,350, 89, 88, 88, 88,
-336,336, 96, 96, 96,115, 96, 96,337,337,351,351,119, 88, 88, 88,
- 89, 89, 96,345, 96, 89, 96, 96,352,352,353,353,347, 88, 88, 89,
+351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359,
+351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359,
+351,351,351,351,351,351,351,351,359,359,359,359,359,359,359,359,
+351,351, 99,360, 99, 92, 99, 99,352,352,361,361,362, 91,363, 91,
+ 91, 91, 99,360, 99, 92, 99, 99,364,364,364,364,362, 91, 91, 91,
+351,351, 99, 99, 92, 92, 99, 99,352,352,365,365, 92, 91, 91, 91,
+351,351, 99, 99, 99,118, 99, 99,352,352,366,366,122, 91, 91, 91,
+ 92, 92, 99,360, 99, 92, 99, 99,367,367,368,368,362, 91, 91, 92,
/* block 61 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16,354,354, 16, 16,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16,369,369, 16, 16,
7, 7, 7, 7, 7, 7, 2, 2, 15, 19, 4, 15, 15, 19, 4, 15,
- 2, 2, 2, 2, 2, 2, 2, 2,355,356, 16, 16, 16, 16, 16, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2,370,371, 16, 16, 16, 16, 16, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 19, 2, 2, 2, 2, 11,
11, 2, 2, 2, 6, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 6, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
- 16, 16, 16, 16, 16, 89, 89, 89, 89, 89, 16, 16, 16, 16, 16, 16,
- 17, 82, 89, 89, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 82,
+ 16, 16, 16, 16, 16, 92, 92, 92, 92, 92, 16, 16, 16, 16, 16, 16,
+ 17, 84, 92, 92, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 84,
/* block 62 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 89,
- 82, 82, 82, 82, 82, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 92,
+ 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 92, 92, 92,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,357,357,357,
-357, 84,357,357,357, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,372,372,372,
+372, 87,372,372,372, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 63 */
- 13, 13,358, 13, 13, 13, 13,358, 13, 13,359,358,358,358,359,359,
-358,358,358,359, 13,358, 13, 13, 13,358,358,358,358,358, 13, 13,
- 13, 13, 13, 13,358, 13,360, 13,358, 13,361,362,358,358, 13,359,
-358,358,363,358,359,329,329,329,329,359, 13, 13,359,359,358,358,
- 6, 6, 6, 6, 6,358,359,359,359,359, 13, 6, 13, 13,364, 13,
+ 13, 13,373, 13, 13, 13, 13,373, 13, 13,374,373,373,373,374,374,
+373,373,373,374, 13,373, 13, 13, 6,373,373,373,373,373, 13, 13,
+ 13, 13, 13, 13,373, 13,375, 13,373, 13,376,377,373,373, 13,374,
+373,373,378,373,374,344,344,344,344,374, 13, 13,374,374,373,373,
+ 6, 6, 6, 6, 6,373,374,374,374,374, 13, 6, 13, 13,379, 13,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
-366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,366,
+380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
/* block 64 */
-367,367,367, 21, 22,367,367,367,367, 17, 89, 89, 89, 89, 89, 89,
+382,382,382, 22, 23,382,382,382,382, 17, 92, 92, 92, 92, 92, 92,
6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 6, 6, 13, 13, 13, 13,
6, 13, 13, 6, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 6, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
@@ -1778,16 +1827,16 @@
6, 6, 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6,
- 6, 6, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 68 */
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
@@ -1795,10 +1844,10 @@
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13,368,368,368,368,368,368,368,368,368,368,
-368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,368,
-369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
-369,369,369,369,369,369,369,369,369,369, 17, 17, 17, 17, 17, 17,
+ 13, 13, 13, 13, 13, 13,383,383,383,383,383,383,383,383,383,383,
+383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,
+384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,
+384,384,384,384,384,384,384,384,384,384, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
/* block 70 */
@@ -1832,46 +1881,36 @@
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
/* block 73 */
+ 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 89, 13, 89, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-
-/* block 74 */
- 89, 13, 13, 13, 13, 89, 13, 13, 13, 13, 89, 89, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 89, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 13, 89, 13,
- 13, 13, 13, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89,
- 89, 13, 13, 13, 13, 13, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5,
+ 13, 13, 13, 13, 13, 13, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5,
4, 5, 4, 5, 4, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-/* block 75 */
+/* block 74 */
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 13, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13,
+ 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 89, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89,
- 6, 6, 6, 6, 6, 4, 5, 6, 6, 6, 6, 89, 6, 89, 89, 89,
+ 6, 6, 6, 6, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-/* block 76 */
-370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
-370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
-370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
-370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
-370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
-370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
-370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
-370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+/* block 75 */
+385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,
+385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,
+385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,
+385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,
+385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,
+385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,
+385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,
+385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,
-/* block 77 */
+/* block 76 */
6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4,
5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
@@ -1881,145 +1920,155 @@
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 6, 6,
-/* block 78 */
+/* block 77 */
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 13, 13, 6, 6, 6, 6, 6, 6, 89, 89, 89,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 6, 6, 6, 6, 6, 13, 13, 6, 6, 6, 6, 6, 6, 92, 92, 92,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 78 */
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 79 */
-371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,
-371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,371,
-371,371,371,371,371,371,371,371,371,371,371,371,371,371,371, 89,
-372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,
-372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,372,
-372,372,372,372,372,372,372,372,372,372,372,372,372,372,372, 89,
- 21, 22,373,374,375,376,377, 21, 22, 21, 22, 21, 22,378,379,380,
-381, 14, 21, 22, 14, 21, 22, 14, 14, 14, 14, 14, 14, 82,382,382,
+386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,
+386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,386,
+386,386,386,386,386,386,386,386,386,386,386,386,386,386,386, 92,
+387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
+387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
+387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, 92,
+ 22, 23,388,389,390,391,392, 22, 23, 22, 23, 22, 23,393,394,395,
+396, 20, 22, 23, 20, 22, 23, 20, 20, 20, 20, 20, 84, 84,397,397,
/* block 80 */
-111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112,
-111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112,
-111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112,
-111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112,
-111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112,
-111,112,111,112,111,112,111,112,111,112,111,112,111,112,111,112,
-111,112,111,112,383,384,384,384,384,384,384,111,112,111,112,385,
-385,385, 89, 89, 89, 89, 89, 89, 89,386,386,386,386,387,386,386,
+114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,
+114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,
+114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,
+114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,
+114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,
+114,115,114,115,114,115,114,115,114,115,114,115,114,115,114,115,
+114,115,114,115,398,399,399,399,399,399,399,114,115,114,115,400,
+400,400,114,115, 92, 92, 92, 92, 92,401,401,401,401,402,401,401,
/* block 81 */
-388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,
-388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,388,
-388,388,388,388,388,388, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,
-389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,
-389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,389,
-389,389,389,389,389,389, 89, 89, 89, 89, 89, 89, 89, 89, 89,390,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,
+403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,
+403,403,403,403,403,403, 92,403, 92, 92, 92, 92, 92,403, 92, 92,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404, 92, 92, 92, 92, 92, 92, 92,405,
+406, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,407,
/* block 82 */
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89,
-248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89,
-248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89,
-248,248,248,248,248,248,248, 89,248,248,248,248,248,248,248, 89,
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
-128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92,
+258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92,
+258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92,
+258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
/* block 83 */
2, 2, 15, 19, 15, 19, 2, 2, 2, 15, 19, 2, 15, 19, 2, 2,
2, 2, 2, 2, 2, 2, 2, 7, 2, 2, 7, 2, 15, 19, 2, 2,
- 15, 19, 4, 5, 4, 5, 4, 5, 4, 5, 2, 2, 2, 2, 2, 83,
- 2, 2, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 15, 19, 4, 5, 4, 5, 4, 5, 4, 5, 2, 2, 2, 2, 2, 85,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 7, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 84 */
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391, 89,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408, 92,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 85 */
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
/* block 86 */
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92,
/* block 87 */
- 1, 2, 2, 2, 13,392,329,393, 4, 5, 4, 5, 4, 5, 4, 5,
+ 1, 2, 2, 2, 13,409,344,410, 4, 5, 4, 5, 4, 5, 4, 5,
4, 5, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5, 7, 4, 5, 5,
- 13,393,393,393,393,393,393,393,393,393, 84, 84, 84, 84, 84, 84,
- 7, 83, 83, 83, 83, 83, 13, 13,393,393,393,392,329, 2, 13, 13,
- 89,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,
-394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,
-394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,
-394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,
+ 13,410,410,410,410,410,410,410,410,410, 87, 87, 87, 87,411,411,
+ 7, 85, 85, 85, 85, 85, 13, 13,410,410,410,409,344, 2, 13, 13,
+ 92,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
+412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
+412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
+412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
/* block 88 */
-394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,
-394,394,394,394,394,394,394, 89, 89, 84, 84, 10, 10,395,395,394,
- 7,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
-396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
-396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
-396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
-396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
-396,396,396,396,396,396,396,396,396,396,396, 2, 83,397,397,396,
+412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
+412,412,412,412,412,412,412, 92, 92, 87, 87, 10, 10,413,413,412,
+ 7,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414, 2, 85,415,415,414,
/* block 89 */
- 89, 89, 89, 89, 89,398,398,398,398,398,398,398,398,398,398,398,
-398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,
-398,398,398,398,398,398,398,398,398,398,398,398,398,398, 89, 89,
- 89,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+ 92, 92, 92, 92, 92,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416, 92, 92,
+ 92,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
/* block 90 */
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, 89,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 92,
13, 13, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,
-398,398,398,398,398,398,398,398, 89, 89, 89, 89, 89, 89, 89, 89,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416, 92, 92, 92, 92, 92,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
+ 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
/* block 91 */
-399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,
-399,399,399,399,399,399,399,399,399,399,399,399,399,399,399, 89,
+417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,
+417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, 92,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 17, 17, 17, 17, 17, 17, 17, 17,
13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,
-399,399,399,399,399,399,399,399,399,399,399,399,399,399,399, 13,
+417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,
+417,417,417,417,417,417,417,417,417,417,417,417,417,417,417, 13,
/* block 92 */
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13,
@@ -2027,551 +2076,661 @@
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
-400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
-400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, 89,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418, 92,
/* block 93 */
-400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
-400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
-400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
-400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
-400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
-400,400,400,400,400,400,400,400, 13, 13, 13, 13, 13, 13, 13, 13,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
/* block 94 */
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
/* block 95 */
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
/* block 96 */
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 97 */
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,403,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,421,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
/* block 98 */
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
-402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,402,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
+420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,420,
/* block 99 */
-402,402,402,402,402,402,402,402,402,402,402,402,402, 89, 89, 89,
-404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
-404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
-404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
-404,404,404,404,404,404,404, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,
-405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,405,
-405,405,405,405,405,405,405,405,406,406,406,406,406,406,407,407,
+420,420,420,420,420,420,420,420,420,420,420,420,420, 92, 92, 92,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,
+423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,
+423,423,423,423,423,423,423,423,424,424,424,424,424,424,425,425,
/* block 100 */
-408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
-408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
-408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
-408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
-408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
-408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
-408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
-408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
+426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
+426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
+426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
+426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
+426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
+426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
+426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
/* block 101 */
-408,408,408,408,408,408,408,408,408,408,408,408,409,410,410,410,
-408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
-411,411,411,411,411,411,411,411,411,411,408,408, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
- 89, 89,125,126,125,126,125,126,125,126,125,126,125,126,412,128,
-129,129,129,413, 89, 89, 89, 89, 89, 89, 89, 89,128,128,413,331,
+426,426,426,426,426,426,426,426,426,426,426,426,427,428,428,428,
+426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
+429,429,429,429,429,429,429,429,429,429,426,426, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,430,131,
+132,132,132,431,131,131,131,131,131,131,131,131,131,131,431,346,
/* block 102 */
-125,126,125,126,125,126,125,126,125,126,125,126,125,126,125,126,
-125,126,125,126,125,126,125,126, 89, 89, 89, 89, 89, 89, 89, 89,
-414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
-414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
-414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
-414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
-414,414,414,414,414,414,415,415,415,415,415,415,415,415,415,415,
-416,416,417,417,417,417,417,417, 89, 89, 89, 89, 89, 89, 89, 89,
+128,129,128,129,128,129,128,129,128,129,128,129,128,129,128,129,
+128,129,128,129,128,129,128,129, 92, 92, 92, 92, 92, 92, 92,131,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,433,433,433,433,433,433,433,433,433,433,
+434,434,435,435,435,435,435,435, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 103 */
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 10, 10, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 14, 14, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
- 82, 14, 14, 14, 14, 14, 14, 14, 14, 21, 22, 21, 22,418, 21, 22,
+ 10, 10, 10, 10, 10, 10, 10, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 10, 10, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 20, 20, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,
+ 84, 20, 20, 20, 20, 20, 20, 20, 20, 22, 23, 22, 23,436, 22, 23,
/* block 104 */
- 21, 22, 21, 22, 21, 22, 21, 22, 83, 10, 10, 21, 22, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 45, 45, 45, 45, 45,
+ 22, 23, 22, 23, 22, 23, 22, 23, 85, 10, 10, 22, 23,437, 20, 92,
+ 22, 23, 22, 23, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 22, 23, 22, 23, 22, 23, 22, 23, 22, 23,438, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 84, 84, 20, 14, 14, 14, 14, 14,
/* block 105 */
-419,419,420,419,419,419,420,419,419,419,419,420,419,419,419,419,
-419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
-419,419,419,421,421,420,420,421,422,422,422,422, 89, 89, 89, 89,
- 17, 17, 17, 17, 17, 17, 13, 13, 3, 13, 89, 89, 89, 89, 89, 89,
-423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,
-423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,
-423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,
-423,423,423,423,424,424,424,424, 89, 89, 89, 89, 89, 89, 89, 89,
+439,439,440,439,439,439,440,439,439,439,439,440,439,439,439,439,
+439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
+439,439,439,441,441,440,440,441,442,442,442,442, 92, 92, 92, 92,
+ 17, 17, 17, 17, 17, 17, 13, 13, 3, 13, 92, 92, 92, 92, 92, 92,
+443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,
+443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,
+443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,443,
+443,443,443,443,444,444,444,444, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 106 */
-425,425,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,425,425,425,425,425,425,425,425,425,425,425,425,
-425,425,425,425,427, 89, 89, 89, 89, 89, 89, 89, 89, 89,428,428,
-429,429,429,429,429,429,429,429,429,429, 89, 89, 89, 89, 89, 89,
-167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
-167,167,169,169,169,169,169,169,430,430,430,169, 89, 89, 89, 89,
+445,445,446,446,446,446,446,446,446,446,446,446,446,446,446,446,
+446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,
+446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,446,
+446,446,446,446,445,445,445,445,445,445,445,445,445,445,445,445,
+445,445,445,445,447, 92, 92, 92, 92, 92, 92, 92, 92, 92,448,448,
+449,449,449,449,449,449,449,449,449,449, 92, 92, 92, 92, 92, 92,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,176,176,176,176,176,176,178,178,178,176, 92, 92, 92, 92,
/* block 107 */
-431,431,431,431,431,431,431,431,431,431,432,432,432,432,432,432,
-432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
-432,432,432,432,432,432,433,433,433,433,433,433,433,433,434,434,
-435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,
-435,435,435,435,435,435,435,436,436,436,436,436,436,436,436,436,
-436,436,437,437, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,438,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247, 89, 89, 89,
+450,450,450,450,450,450,450,450,450,450,451,451,451,451,451,451,
+451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,
+451,451,451,451,451,451,452,452,452,452,452,452,452,452,453,453,
+454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,454,
+454,454,454,454,454,454,454,455,455,455,455,455,455,455,455,455,
+455,455,456,456, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,457,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257, 92, 92, 92,
/* block 108 */
-439,439,439,440,441,441,441,441,441,441,441,441,441,441,441,441,
-441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
-441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
-441,441,441,439,440,440,439,439,439,439,440,440,439,440,440,440,
-440,442,442,442,442,442,442,442,442,442,442,442,442,442, 89,443,
-444,444,444,444,444,444,444,444,444,444, 89, 89, 89, 89,442,442,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+458,458,458,459,460,460,460,460,460,460,460,460,460,460,460,460,
+460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
+460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
+460,460,460,458,459,459,458,458,458,458,459,459,458,459,459,459,
+459,461,461,461,461,461,461,461,461,461,461,461,461,461, 92,462,
+463,463,463,463,463,463,463,463,463,463, 92, 92, 92, 92,461,461,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 109 */
-445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,
-445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,445,
-445,445,445,445,445,445,445,445,445,446,446,446,446,446,446,447,
-447,446,446,447,447,446,446, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-445,445,445,446,445,445,445,445,445,445,445,445,446,447, 89, 89,
-448,448,448,448,448,448,448,448,448,448, 89, 89,449,449,449,449,
-238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
-450,238,238,238,238,238,238,243,243,243,238,239, 89, 89, 89, 89,
+464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,
+464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,
+464,464,464,464,464,464,464,464,464,465,465,465,465,465,465,466,
+466,465,465,466,466,465,465, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+464,464,464,465,464,464,464,464,464,464,464,464,465,466, 92, 92,
+467,467,467,467,467,467,467,467,467,467, 92, 92,468,468,468,468,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+469,248,248,248,248,248,248,253,253,253,248,249, 92, 92, 92, 92,
/* block 110 */
-451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,
-451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,
-451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,451,
-452,451,452,452,452,451,451,452,452,451,451,451,451,451,452,452,
-451,452,451, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,451,451,453,454,454,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,
+470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,
+470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,
+471,470,471,471,471,470,470,471,471,470,470,470,470,470,471,471,
+470,471,470, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,470,470,472,473,473,
+474,474,474,474,474,474,474,474,474,474,474,475,476,476,475,475,
+477,477,474,478,478,475,476, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 111 */
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,
-455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,455,
-455,455,455,456,456,457,456,456,457,456,456,458,456,457, 89, 89,
-459,459,459,459,459,459,459,459,459,459, 89, 89, 89, 89, 89, 89,
+ 92,258,258,258,258,258,258, 92, 92,258,258,258,258,258,258, 92,
+ 92,258,258,258,258,258,258, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+258,258,258,258,258,258,258, 92,258,258,258,258,258,258,258, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 112 */
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247, 89, 89, 89, 89,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247, 89, 89, 89, 89,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
+474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
+474,474,474,475,475,476,475,475,476,475,475,477,475,476, 92, 92,
+479,479,479,479,479,479,479,479,479,479, 92, 92, 92, 92, 92, 92,
/* block 113 */
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
-460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257, 92, 92, 92, 92,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257, 92, 92, 92, 92,
/* block 114 */
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
/* block 115 */
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401, 89, 89,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401, 89, 89,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
/* block 116 */
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
/* block 117 */
- 14, 14, 14, 14, 14, 14, 14, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89,136,136,136,136,136, 89, 89, 89, 89, 89,141,138,141,
-141,141,141,141,141,141,141,141,141,462,141,141,141,141,141,141,
-141,141,141,141,141,141,141, 89,141,141,141,141,141, 89,141, 89,
-141,141, 89,141,141, 89,141,141,141,141,141,141,141,141,141,141,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 118 */
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+ 20, 20, 20, 20, 20, 20, 20, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92,139,139,139,139,139, 92, 92, 92, 92, 92,145,142,145,
+145,145,145,145,145,145,145,145,145,482,145,145,145,145,145,145,
+145,145,145,145,145,145,145, 92,145,145,145,145,145, 92,145, 92,
+145,145, 92,145,145, 92,145,145,145,145,145,145,145,145,145,145,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
/* block 119 */
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
+483,483, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
/* block 120 */
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147, 4, 5,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
/* block 121 */
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
- 89, 89,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-147,147,147,147,147,147,147,147,147,147,147,147,144, 13, 89, 89,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152, 4, 5,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
/* block 122 */
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 2, 2, 2, 2, 2, 2, 2, 4, 5, 2, 89, 89, 89, 89, 89, 89,
- 84, 84, 84, 84, 84, 84, 84, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 2, 7, 7, 11, 11, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4,
- 5, 4, 5, 4, 5, 2, 2, 4, 5, 2, 2, 2, 2, 11, 11, 11,
- 2, 2, 2, 89, 2, 2, 2, 2, 7, 4, 5, 4, 5, 4, 5, 2,
- 2, 2, 6, 7, 6, 6, 6, 89, 2, 3, 2, 2, 89, 89, 89, 89,
-147,147,147,147,147, 89,147,147,147,147,147,147,147,147,147,147,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+ 92, 92,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+152,152,152,152,152,152,152,152,152,152,152,152,149, 13, 92, 92,
/* block 123 */
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
-147,147,147,147,147,147,147,147,147,147,147,147,147, 89, 89, 16,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 2, 2, 2, 2, 2, 2, 2, 4, 5, 2, 92, 92, 92, 92, 92, 92,
+ 87, 87, 87, 87, 87, 87, 87, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 2, 7, 7, 11, 11, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4,
+ 5, 4, 5, 4, 5, 2, 2, 4, 5, 2, 2, 2, 2, 11, 11, 11,
+ 2, 2, 2, 92, 2, 2, 2, 2, 7, 4, 5, 4, 5, 4, 5, 2,
+ 2, 2, 6, 7, 6, 6, 6, 92, 2, 3, 2, 2, 92, 92, 92, 92,
+152,152,152,152,152, 92,152,152,152,152,152,152,152,152,152,152,
/* block 124 */
- 89, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 16,
+
+/* block 125 */
+ 92, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 6, 6, 6, 2,
2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 2, 5, 10, 11,
10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 6, 5, 6, 4,
- 5, 2, 4, 5, 2, 2,396,396,396,396,396,396,396,396,396,396,
- 83,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
-
-/* block 125 */
-396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,
-396,396,396,396,396,396,396,396,396,396,396,396,396,396, 83, 83,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, 89,
- 89, 89,247,247,247,247,247,247, 89, 89,247,247,247,247,247,247,
- 89, 89,247,247,247,247,247,247, 89, 89,247,247,247, 89, 89, 89,
- 3, 3, 6, 10, 13, 3, 3, 89, 13, 6, 6, 6, 6, 13, 13, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 16, 16, 16, 13, 13, 89, 89,
+ 5, 2, 4, 5, 2, 2,414,414,414,414,414,414,414,414,414,414,
+ 85,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
/* block 126 */
-463,463,463,463,463,463,463,463,463,463,463,463, 89,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463, 89,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463, 89,463,463, 89,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463, 89, 89,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414, 85, 85,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,257,
+257,257,257,257,257,257,257,257,257,257,257,257,257,257,257, 92,
+ 92, 92,257,257,257,257,257,257, 92, 92,257,257,257,257,257,257,
+ 92, 92,257,257,257,257,257,257, 92, 92,257,257,257, 92, 92, 92,
+ 3, 3, 6, 10, 13, 3, 3, 92, 13, 6, 6, 6, 6, 13, 13, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 16, 16, 16, 13, 13, 92, 92,
/* block 127 */
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463, 89, 89, 89, 89, 89,
+484,484,484,484,484,484,484,484,484,484,484,484, 92,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484, 92,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484, 92,484,484, 92,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484, 92, 92,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 128 */
- 2, 2, 13, 89, 89, 89, 89, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484, 92, 92, 92, 92, 92,
+
+/* block 129 */
+ 2, 2, 2, 92, 92, 92, 92, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 17, 17, 89, 89, 89, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,
-464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,
-464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,
-464,464,464,464,464,465,465,465,465,466,466,466,466,466,466,466,
+ 17, 17, 17, 17, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,486,486,486,486,487,487,487,487,487,487,487,
-/* block 129 */
-466,466,466,466,466,466,466,466,466,466,465, 89, 89, 89, 89, 89,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+/* block 130 */
+487,487,487,487,487,487,487,487,487,487,486, 92, 92, 92, 92, 92,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 84, 89, 89,
-
-/* block 130 */
-467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
-467,467,467,467,467,467,467,467,467,467,467,467,467, 89, 89, 89,
-468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,
-468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,
-468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,
-468, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 87, 92, 92,
/* block 131 */
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,469, 89,
-470,470,470,470, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,
-471,472,471,471,471,471,471,471,471,471,472, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
+488,488,488,488,488,488,488,488,488,488,488,488,488, 92, 92, 92,
+489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,
+489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,
+489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,
+489, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 132 */
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473, 89,474,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475, 89, 89, 89, 89,475,475,475,475,475,475,475,475,
-476,477,477,477,477,477, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,
+490,490,490,490,490,490,490,490,490,490,490,490,490,490,490, 92,
+491,491,491,491, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
+492,493,492,492,492,492,492,492,492,492,493, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 133 */
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
-478,478,478,478,478,478,478,478,479,479,479,479,479,479,479,479,
-479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
-479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
-480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
-480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
-480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,
+494,494,494,494,494,494,494,494,494,494,494,494,494,494, 92,495,
+496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,
+496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,
+496,496,496,496, 92, 92, 92, 92,496,496,496,496,496,496,496,496,
+497,498,498,498,498,498, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 134 */
-481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
-481,481,481,481,481,481,481,481,481,481,481,481,481,481, 89, 89,
-482,482,482,482,482,482,482,482,482,482, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
+499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
+499,499,499,499,499,499,499,499,500,500,500,500,500,500,500,500,
+500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,
+500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,
+501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,
+501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,
+501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,
/* block 135 */
-483,483,483,483,483,483, 89, 89,483, 89,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
-483,483,483,483,483,483, 89,483,483, 89, 89, 89,483, 89, 89,483,
-484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
-484,484,484,484,484,484, 89,485,486,486,486,486,486,486,486,486,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
+502,502,502,502,502,502,502,502,502,502,502,502,502,502, 92, 92,
+503,503,503,503,503,503,503,503,503,503, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 136 */
-487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,
-487,487,487,487,487,487,488,488,488,488,488,488, 89, 89, 89,489,
-490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,490,
-490,490,490,490,490,490,490,490,490,490, 89, 89, 89, 89, 89,491,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+504,504,504,504,504,504, 92, 92,504, 92,504,504,504,504,504,504,
+504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
+504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
+504,504,504,504,504,504, 92,504,504, 92, 92, 92,504, 92, 92,504,
+505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
+505,505,505,505,505,505, 92,506,507,507,507,507,507,507,507,507,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 137 */
-492,493,493,493, 89,493,493, 89, 89, 89, 89, 89,493,493,493,493,
-492,492,492,492, 89,492,492,492, 89,492,492,492,492,492,492,492,
-492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,
-492,492,492,492, 89, 89, 89, 89,493,493,493, 89, 89, 89, 89,493,
-494,494,494,494,494,494,494,494, 89, 89, 89, 89, 89, 89, 89, 89,
-495,495,495,495,495,495,495,495,495, 89, 89, 89, 89, 89, 89, 89,
-496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,
-496,496,496,496,496,496,496,496,496,496,496,496,496,497,497,498,
+508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,
+508,508,508,508,508,508,509,509,509,509,509,509, 92, 92, 92,510,
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+511,511,511,511,511,511,511,511,511,511, 92, 92, 92, 92, 92,512,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 138 */
-499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
-499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
-499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
-499,499,499,499,499,499, 89, 89, 89,500,500,500,500,500,500,500,
-501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,501,
-501,501,501,501,501,501, 89, 89,502,502,502,502,502,502,502,502,
-503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,
-503,503,503, 89, 89, 89, 89, 89,504,504,504,504,504,504,504,504,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514, 92, 92, 92, 92, 92, 92,514,514,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 139 */
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+515,516,516,516, 92,516,516, 92, 92, 92, 92, 92,516,516,516,516,
+515,515,515,515, 92,515,515,515, 92,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515, 92, 92, 92, 92,516,516,516, 92, 92, 92, 92,516,
+517,517,517,517,517,517,517,517, 92, 92, 92, 92, 92, 92, 92, 92,
+518,518,518,518,518,518,518,518,518, 92, 92, 92, 92, 92, 92, 92,
+519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
+519,519,519,519,519,519,519,519,519,519,519,519,519,520,520,521,
/* block 140 */
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,
-506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, 89,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522, 92, 92, 92,523,523,523,523,523,523,523,
+524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,
+524,524,524,524,524,524, 92, 92,525,525,525,525,525,525,525,525,
+526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,
+526,526,526, 92, 92, 92, 92, 92,527,527,527,527,527,527,527,527,
/* block 141 */
-507,507,508,509,509,509,509,509,509,509,509,509,509,509,509,509,
-509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
-509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,
-508,508,508,507,507,507,507,508,508,507,507,510,510,511,510,510,
-510,510, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,
+528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,
+528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,
+528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,
+528,528,528,528,528,528,528,528,528, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 142 */
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, 92,
/* block 143 */
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
-512,512,512,512,512,512,512,512,512,512,512,512,512,512,512, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+530,531,530,532,532,532,532,532,532,532,532,532,532,532,532,532,
+532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,
+532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,532,
+532,532,532,532,532,532,532,532,531,531,531,531,531,531,531,531,
+531,531,531,531,531,531,531,533,533,533,533,533,533,533, 92, 92,
+ 92, 92,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,535,535,535,535,535,535,535,535,535,535,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 144 */
-513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
-513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
-513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
-513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
-513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
-513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
-513,513,513, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
-514,514,514,514, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+536,536,537,538,538,538,538,538,538,538,538,538,538,538,538,538,
+538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
+538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
+537,537,537,536,536,536,536,537,537,536,536,539,539,540,539,539,
+539,539, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,
+541,541,541,541,541,541,541,541,541, 92, 92, 92, 92, 92, 92, 92,
+542,542,542,542,542,542,542,542,542,542, 92, 92, 92, 92, 92, 92,
/* block 145 */
-515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
-515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
-515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
-515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
-515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
-515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
-515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
-515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+543,543,543,544,544,544,544,544,544,544,544,544,544,544,544,544,
+544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,
+544,544,544,544,544,544,544,543,543,543,543,543,545,543,543,543,
+543,543,543,543,543, 92,546,546,546,546,546,546,546,546,546,546,
+547,547,547,547, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 146 */
-515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
-515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
-515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+548,548,549,550,550,550,550,550,550,550,550,550,550,550,550,550,
+550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,
+550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,
+550,550,550,549,549,549,548,548,548,548,548,548,548,548,548,549,
+549,550,550,550,550,551,551,551,551, 92, 92, 92, 92, 92, 92, 92,
+552,552,552,552,552,552,552,552,552,552, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
/* block 147 */
+553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,
+553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,
+553,553,553,553,553,553,553,553,553,553,553,554,555,554,555,555,
+554,554,554,554,554,554,555,554, 92, 92, 92, 92, 92, 92, 92, 92,
+556,556,556,556,556,556,556,556,556,556, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 148 */
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+
+/* block 149 */
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 150 */
+558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
+558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
+558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
+558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
+558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
+558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
+558,558,558, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+559,559,559,559, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 151 */
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+
+/* block 152 */
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 153 */
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+
+/* block 154 */
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
+432,432,432,432,432,432,432,432,432, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 155 */
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
+561,561,561,561,561, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+561,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
+562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
+562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, 92,
+
+/* block 156 */
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,563,
+563,563,563,564,564,564,564,564,564,564,564,564,564,564,564,564,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 157 */
+414,412, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 158 */
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
@@ -2579,211 +2738,321 @@
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-/* block 148 */
+/* block 159 */
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 89, 89, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 92, 92, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13,328,328, 84, 84, 84, 13, 13, 13,328,328,328,
-328,328,328, 16, 16, 16, 16, 16, 16, 16, 16, 84, 84, 84, 84, 84,
+ 13, 13, 13, 13, 13,343,343, 87, 87, 87, 13, 13, 13,343,343,343,
+343,343,343, 16, 16, 16, 16, 16, 16, 16, 16, 87, 87, 87, 87, 87,
-/* block 149 */
- 84, 84, 84, 13, 13, 84, 84, 84, 84, 84, 84, 84, 13, 13, 13, 13,
+/* block 160 */
+ 87, 87, 87, 13, 13, 87, 87, 87, 87, 87, 87, 87, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 84, 84, 84, 84, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 87, 87, 87, 87, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-/* block 150 */
-466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
-466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
-466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
-466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
-466,466,516,516,516,466, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+/* block 161 */
+487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,
+487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,
+487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,
+487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,
+487,487,565,565,565,487, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-/* block 151 */
+/* block 162 */
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 17, 17, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-/* block 152 */
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,359,359,
-359,359,359,359,359, 89,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+/* block 163 */
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,374,374,
+374,374,374,374,374, 92,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
-/* block 153 */
-358,358,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,358, 89,358,358,
- 89, 89,358, 89, 89,358,358, 89, 89,358,358,358,358, 89,358,358,
-358,358,358,358,358,358,359,359,359,359, 89,359, 89,359,359,359,
-359,359,359,359, 89,359,359,359,359,359,359,359,359,359,359,359,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+/* block 164 */
+373,373,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,373, 92,373,373,
+ 92, 92,373, 92, 92,373,373, 92, 92,373,373,373,373, 92,373,373,
+373,373,373,373,373,373,374,374,374,374, 92,374, 92,374,374,374,
+374,374,374,374, 92,374,374,374,374,374,374,374,374,374,374,374,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
-/* block 154 */
-359,359,359,359,358,358, 89,358,358,358,358, 89, 89,358,358,358,
-358,358,358,358,358, 89,358,358,358,358,358,358,358, 89,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,358,358, 89,358,358,358,358, 89,
-358,358,358,358,358, 89,358, 89, 89, 89,358,358,358,358,358,358,
-358, 89,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+/* block 165 */
+374,374,374,374,373,373, 92,373,373,373,373, 92, 92,373,373,373,
+373,373,373,373,373, 92,373,373,373,373,373,373,373, 92,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,373,373, 92,373,373,373,373, 92,
+373,373,373,373,373, 92,373, 92, 92, 92,373,373,373,373,373,373,
+373, 92,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
-/* block 155 */
-358,358,358,358,358,358,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+/* block 166 */
+373,373,373,373,373,373,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
-/* block 156 */
-359,359,359,359,359,359,359,359,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+/* block 167 */
+374,374,374,374,374,374,374,374,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
-/* block 157 */
-358,358,358,358,358,358,358,358,358,358,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359, 89, 89,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358, 6,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359, 6,359,359,359,359,
-359,359,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358, 6,359,359,359,359,
+/* block 168 */
+373,373,373,373,373,373,373,373,373,373,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374, 92, 92,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
+373, 6,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374, 6,374,374,374,374,
+374,374,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,373, 6,374,374,374,374,
-/* block 158 */
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359, 6,359,359,359,359,359,359,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358, 6,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, 6,
-359,359,359,359,359,359,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, 6,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+/* block 169 */
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374, 6,374,374,374,374,374,374,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373, 6,374,374,374,374,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374, 6,
+374,374,374,374,374,374,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, 6,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
-/* block 159 */
-359,359,359,359,359,359,359,359,359, 6,359,359,359,359,359,359,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358, 6,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359, 6,359,359,359,359,359,359,358,359, 89, 89, 8, 8,
+/* block 170 */
+374,374,374,374,374,374,374,374,374, 6,374,374,374,374,374,374,
+373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373, 6,374,374,374,374,374,374,
+374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,374,
+374,374,374, 6,374,374,374,374,374,374,373,374, 92, 92, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-/* block 160 */
+/* block 171 */
+152,152,152,152, 92,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+ 92,152,152, 92,152, 92, 92,152, 92,152,152,152,152,152,152,152,
+152,152,152, 92,152,152,152,152, 92,152, 92,152, 92, 92, 92, 92,
+ 92, 92,152, 92, 92, 92, 92,152, 92,152, 92,152, 92,152,152,152,
+ 92,152,152, 92,152, 92, 92,152, 92,152, 92,152, 92,152, 92,152,
+ 92,152,152, 92,152, 92, 92,152,152,152,152, 92,152,152,152,152,
+152,152,152, 92,152,152,152,152, 92,152,152,152,152, 92,152, 92,
+
+/* block 172 */
+152,152,152,152,152,152,152,152,152,152, 92,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92, 92,
+ 92,152,152,152, 92,152,152,152,152,152, 92,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+147,147, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 173 */
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-/* block 161 */
+/* block 174 */
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92,
+ 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92,
+ 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-/* block 162 */
- 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 89, 89, 89, 89, 89,
+/* block 175 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 92, 92, 92, 92, 92,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 89,
- 89, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 13, 89, 13,
- 89, 89, 13, 89, 89, 89, 13, 89, 89, 89, 13, 13, 13, 13, 13, 89,
- 89, 89, 89, 89, 89, 89, 89, 13, 89, 89, 89, 89, 89, 89, 89, 13,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 13, 89, 13, 13, 89, 89, 13,
-/* block 163 */
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 13, 13, 13, 13, 89, 89,
- 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+/* block 176 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-/* block 164 */
-517, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+/* block 177 */
+566, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92,
+ 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-/* block 165 */
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+/* block 178 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 13, 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92,
-/* block 166 */
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+/* block 179 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-/* block 167 */
-401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
-401,401,401,401,401,401,401,401,401,401,401,401,401,401, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+/* block 180 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92,
+ 13, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-/* block 168 */
- 89, 16, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+/* block 181 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 92, 13, 13, 13, 13, 92, 92, 92,
+
+/* block 182 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 92, 92,
+ 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 183 */
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 13, 13, 13, 13, 13,
+
+/* block 184 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 92, 92, 92, 92, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 185 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 186 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 187 */
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 188 */
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+
+/* block 189 */
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+
+/* block 190 */
+ 92, 16, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
@@ -2791,35 +3060,35 @@
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-/* block 169 */
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
-
-/* block 170 */
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
- 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+/* block 191 */
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+
+/* block 192 */
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
-/* block 171 */
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,
-461,461,461,461,461,461,461,461,461,461,461,461,461,461, 89, 89,
+/* block 193 */
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,
+481,481,481,481,481,481,481,481,481,481,481,481,481,481, 92, 92,
};
diff -Nru pcre3-8.12/pcre_valid_utf8.c pcre3-8.31/pcre_valid_utf8.c
--- pcre3-8.12/pcre_valid_utf8.c 2010-11-24 17:38:32.000000000 +0000
+++ pcre3-8.31/pcre_valid_utf8.c 2011-12-28 16:57:51.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2009 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -54,127 +54,246 @@
*************************************************/
/* This function is called (optionally) at the start of compile or match, to
-validate that a supposed UTF-8 string is actually valid. The early check means
+check that a supposed UTF-8 string is actually valid. The early check means
that subsequent code can assume it is dealing with a valid string. The check
-can be turned off for maximum performance, but the consequences of supplying
-an invalid string are then undefined.
+can be turned off for maximum performance, but the consequences of supplying an
+invalid string are then undefined.
Originally, this function checked according to RFC 2279, allowing for values in
the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were in
the canonical format. Once somebody had pointed out RFC 3629 to me (it
obsoletes 2279), additional restrictions were applied. The values are now
limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the
-subrange 0xd000 to 0xdfff is excluded.
+subrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte
+characters is still checked.
+
+From release 8.13 more information about the details of the error are passed
+back in the returned value:
+
+PCRE_UTF8_ERR0 No error
+PCRE_UTF8_ERR1 Missing 1 byte at the end of the string
+PCRE_UTF8_ERR2 Missing 2 bytes at the end of the string
+PCRE_UTF8_ERR3 Missing 3 bytes at the end of the string
+PCRE_UTF8_ERR4 Missing 4 bytes at the end of the string
+PCRE_UTF8_ERR5 Missing 5 bytes at the end of the string
+PCRE_UTF8_ERR6 2nd-byte's two top bits are not 0x80
+PCRE_UTF8_ERR7 3rd-byte's two top bits are not 0x80
+PCRE_UTF8_ERR8 4th-byte's two top bits are not 0x80
+PCRE_UTF8_ERR9 5th-byte's two top bits are not 0x80
+PCRE_UTF8_ERR10 6th-byte's two top bits are not 0x80
+PCRE_UTF8_ERR11 5-byte character is not permitted by RFC 3629
+PCRE_UTF8_ERR12 6-byte character is not permitted by RFC 3629
+PCRE_UTF8_ERR13 4-byte character with value > 0x10ffff is not permitted
+PCRE_UTF8_ERR14 3-byte character with value 0xd000-0xdfff is not permitted
+PCRE_UTF8_ERR15 Overlong 2-byte sequence
+PCRE_UTF8_ERR16 Overlong 3-byte sequence
+PCRE_UTF8_ERR17 Overlong 4-byte sequence
+PCRE_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur)
+PCRE_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur)
+PCRE_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character)
+PCRE_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff
Arguments:
string points to the string
length length of string, or -1 if the string is zero-terminated
+ errp pointer to an error position offset variable
-Returns: < 0 if the string is a valid UTF-8 string
- >= 0 otherwise; the value is the offset of the bad byte
-
-Bad bytes can be:
-
- . An isolated byte whose most significant bits are 0x80, because this
- can only correctly appear within a UTF-8 character;
-
- . A byte whose most significant bits are 0xc0, but whose other bits indicate
- that there are more than 3 additional bytes (i.e. an RFC 2279 starting
- byte, which is no longer valid under RFC 3629);
-
- .
-
-The returned offset may also be equal to the length of the string; this means
-that one or more bytes is missing from the final UTF-8 character.
+Returns: = 0 if the string is a valid UTF-8 string
+ > 0 otherwise, setting the offset of the bad character
*/
int
-_pcre_valid_utf8(USPTR string, int length)
+PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset)
{
-#ifdef SUPPORT_UTF8
-register USPTR p;
+#ifdef SUPPORT_UTF
+register PCRE_PUCHAR p;
if (length < 0)
{
for (p = string; *p != 0; p++);
- length = p - string;
+ length = (int)(p - string);
}
for (p = string; length-- > 0; p++)
{
- register int ab;
- register int c = *p;
- if (c < 128) continue;
- if (c < 0xc0) return p - string;
- ab = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */
- if (ab > 3) return p - string; /* Too many for RFC 3629 */
- if (length < ab) return p + 1 + length - string; /* Missing bytes */
- length -= ab;
+ register int ab, c, d;
+
+ c = *p;
+ if (c < 128) continue; /* ASCII character */
+
+ if (c < 0xc0) /* Isolated 10xx xxxx byte */
+ {
+ *erroroffset = (int)(p - string);
+ return PCRE_UTF8_ERR20;
+ }
+
+ if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */
+ {
+ *erroroffset = (int)(p - string);
+ return PCRE_UTF8_ERR21;
+ }
+
+ ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */
+ if (length < ab)
+ {
+ *erroroffset = (int)(p - string); /* Missing bytes */
+ return ab - length; /* Codes ERR1 to ERR5 */
+ }
+ length -= ab; /* Length remaining */
/* Check top bits in the second byte */
- if ((*(++p) & 0xc0) != 0x80) return p - string;
- /* Check for overlong sequences for each different length, and for the
- excluded range 0xd000 to 0xdfff. */
+ if (((d = *(++p)) & 0xc0) != 0x80)
+ {
+ *erroroffset = (int)(p - string) - 1;
+ return PCRE_UTF8_ERR6;
+ }
+
+ /* For each length, check that the remaining bytes start with the 0x80 bit
+ set and not the 0x40 bit. Then check for an overlong sequence, and for the
+ excluded range 0xd800 to 0xdfff. */
switch (ab)
{
- /* Check for xx00 000x (overlong sequence) */
+ /* 2-byte character. No further bytes to check for 0x80. Check first byte
+ for for xx00 000x (overlong sequence). */
- case 1:
- if ((c & 0x3e) == 0) return p - string;
- continue; /* We know there aren't any more bytes to check */
+ case 1: if ((c & 0x3e) == 0)
+ {
+ *erroroffset = (int)(p - string) - 1;
+ return PCRE_UTF8_ERR15;
+ }
+ break;
- /* Check for 1110 0000, xx0x xxxx (overlong sequence) or
- 1110 1101, 1010 xxxx (0xd000 - 0xdfff) */
+ /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes
+ for 1110 0000, xx0x xxxx (overlong sequence) or
+ 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */
case 2:
- if ((c == 0xe0 && (*p & 0x20) == 0) ||
- (c == 0xed && *p >= 0xa0))
- return p - string;
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if (c == 0xe0 && (d & 0x20) == 0)
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR16;
+ }
+ if (c == 0xed && d >= 0xa0)
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR14;
+ }
break;
- /* Check for 1111 0000, xx00 xxxx (overlong sequence) or
- greater than 0x0010ffff (f4 8f bf bf) */
+ /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2
+ bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a
+ character greater than 0x0010ffff (f4 8f bf bf) */
case 3:
- if ((c == 0xf0 && (*p & 0x30) == 0) ||
- (c > 0xf4 ) ||
- (c == 0xf4 && *p > 0x8f))
- return p - string;
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR8;
+ }
+ if (c == 0xf0 && (d & 0x30) == 0)
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR17;
+ }
+ if (c > 0xf4 || (c == 0xf4 && d > 0x8f))
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR13;
+ }
break;
-#if 0
- /* These cases can no longer occur, as we restrict to a maximum of four
- bytes nowadays. Leave the code here in case we ever want to add an option
- for longer sequences. */
+ /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be
+ rejected by the length test below. However, we do the appropriate tests
+ here so that overlong sequences get diagnosed, and also in case there is
+ ever an option for handling these larger code points. */
+
+ /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for
+ 1111 1000, xx00 0xxx */
- /* Check for 1111 1000, xx00 0xxx */
case 4:
- if (c == 0xf8 && (*p & 0x38) == 0) return p - string;
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR8;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE_UTF8_ERR9;
+ }
+ if (c == 0xf8 && (d & 0x38) == 0)
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE_UTF8_ERR18;
+ }
break;
- /* Check for leading 0xfe or 0xff, and then for 1111 1100, xx00 00xx */
+ /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for
+ 1111 1100, xx00 00xx. */
+
case 5:
- if (c == 0xfe || c == 0xff ||
- (c == 0xfc && (*p & 0x3c) == 0)) return p - string;
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR8;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE_UTF8_ERR9;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */
+ {
+ *erroroffset = (int)(p - string) - 5;
+ return PCRE_UTF8_ERR10;
+ }
+ if (c == 0xfc && (d & 0x3c) == 0)
+ {
+ *erroroffset = (int)(p - string) - 5;
+ return PCRE_UTF8_ERR19;
+ }
break;
-#endif
-
}
- /* Check for valid bytes after the 2nd, if any; all must start 10 */
- while (--ab > 0)
+ /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are
+ excluded by RFC 3629. The pointer p is currently at the last byte of the
+ character. */
+
+ if (ab > 3)
{
- if ((*(++p) & 0xc0) != 0x80) return p - string;
+ *erroroffset = (int)(p - string) - ab;
+ return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12;
}
}
-#else
+
+#else /* SUPPORT_UTF */
(void)(string); /* Keep picky compilers happy */
(void)(length);
#endif
-return -1;
+return PCRE_UTF8_ERR0; /* This indicates success */
}
/* End of pcre_valid_utf8.c */
diff -Nru pcre3-8.12/pcre_version.c pcre3-8.31/pcre_version.c
--- pcre3-8.12/pcre_version.c 2008-07-09 15:51:30.000000000 +0000
+++ pcre3-8.31/pcre_version.c 2011-12-28 16:57:50.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2008 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -79,8 +79,13 @@
pre-processor time. This hack uses a standard trick for avoiding calling
the STRING macro with an empty argument when doing the test. */
+#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
pcre_version(void)
+#else
+PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
+pcre16_version(void)
+#endif
{
return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)?
XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) :
diff -Nru pcre3-8.12/pcre_xclass.c pcre3-8.31/pcre_xclass.c
--- pcre3-8.12/pcre_xclass.c 2010-06-03 19:15:23.000000000 +0000
+++ pcre3-8.31/pcre_xclass.c 2011-12-28 16:57:58.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2010 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -64,39 +64,63 @@
*/
BOOL
-_pcre_xclass(int c, const uschar *data)
+PRIV(xclass)(int c, const pcre_uchar *data, BOOL utf)
{
int t;
BOOL negated = (*data & XCL_NOT) != 0;
+(void)utf;
+#ifdef COMPILE_PCRE8
+/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */
+utf = TRUE;
+#endif
+
/* Character values < 256 are matched against a bitmap, if one is present. If
not, we still carry on, because there may be ranges that start below 256 in the
additional data. */
if (c < 256)
{
- if ((*data & XCL_MAP) != 0 && (data[1 + c/8] & (1 << (c&7))) != 0)
- return !negated; /* char found */
+ if ((*data & XCL_MAP) != 0 &&
+ (((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0)
+ return !negated; /* char found */
}
/* First skip the bit map if present. Then match against the list of Unicode
properties or large chars or ranges that end with a large char. We won't ever
encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */
-if ((*data++ & XCL_MAP) != 0) data += 32;
+if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(pcre_uchar);
while ((t = *data++) != XCL_END)
{
int x, y;
if (t == XCL_SINGLE)
{
- GETCHARINC(x, data);
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ GETCHARINC(x, data); /* macro generates multiple statements */
+ }
+ else
+#endif
+ x = *data++;
if (c == x) return !negated;
}
else if (t == XCL_RANGE)
{
- GETCHARINC(x, data);
- GETCHARINC(y, data);
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ GETCHARINC(x, data); /* macro generates multiple statements */
+ GETCHARINC(y, data); /* macro generates multiple statements */
+ }
+ else
+#endif
+ {
+ x = *data++;
+ y = *data++;
+ }
if (c >= x && c <= y) return !negated;
}
@@ -117,7 +141,7 @@
break;
case PT_GC:
- if ((data[1] == _pcre_ucp_gentype[prop->chartype]) == (t == XCL_PROP))
+ if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP))
return !negated;
break;
@@ -130,28 +154,28 @@
break;
case PT_ALNUM:
- if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N) == (t == XCL_PROP))
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP))
return !negated;
break;
case PT_SPACE: /* Perl space */
- if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
== (t == XCL_PROP))
return !negated;
break;
case PT_PXSPACE: /* POSIX space */
- if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP))
return !negated;
break;
case PT_WORD:
- if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
- _pcre_ucp_gentype[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)
== (t == XCL_PROP))
return !negated;
break;
diff -Nru pcre3-8.12/pcrecpp.cc pcre3-8.31/pcrecpp.cc
--- pcre3-8.12/pcrecpp.cc 2013-03-27 06:36:17.000000000 +0000
+++ pcre3-8.31/pcrecpp.cc 2012-01-15 18:00:31.000000000 +0000
@@ -37,6 +37,7 @@
#include
#include
#include /* for SHRT_MIN, USHRT_MAX, etc */
+#include /* for memcpy */
#include
#include
#include
@@ -79,12 +80,6 @@
// If the user doesn't ask for any options, we just use this one
static RE_Options default_options;
-// PCRE6.x compatible API
-void RE::Init(const char *c_pat, const RE_Options* options) {
- const string cxx_pat(c_pat);
- Init(cxx_pat, options);
-}
-
void RE::Init(const string& pat, const RE_Options* options) {
pattern_ = pat;
if (options == NULL) {
@@ -389,7 +384,6 @@
int vec[kVecSize];
string out;
int start = 0;
- int lastend = -1;
bool last_match_was_empty_string = false;
while (start <= static_cast(str->length())) {
@@ -445,7 +439,6 @@
out.append(*str, start, matchstart - start);
Rewrite(&out, rewrite, *str, vec, matches);
start = matchend;
- lastend = matchend;
count++;
last_match_was_empty_string = (matchstart == matchend);
}
diff -Nru pcre3-8.12/pcrecpp.h pcre3-8.31/pcrecpp.h
--- pcre3-8.12/pcrecpp.h 2013-03-27 06:36:17.000000000 +0000
+++ pcre3-8.31/pcrecpp.h 2010-01-02 16:25:49.000000000 +0000
@@ -658,8 +658,6 @@
private:
void Init(const string& pattern, const RE_Options* options);
- // Old version from PCRE 6.x, for compatibility
- void Init(const char *pattern, const RE_Options* options);
void Cleanup();
// Match against "text", filling in "vec" (up to "vecsize" * 2/3) with
diff -Nru pcre3-8.12/pcrecpp_unittest.cc pcre3-8.31/pcrecpp_unittest.cc
--- pcre3-8.12/pcrecpp_unittest.cc 2010-01-02 16:29:56.000000000 +0000
+++ pcre3-8.31/pcrecpp_unittest.cc 2011-08-21 13:44:57.000000000 +0000
@@ -38,6 +38,7 @@
#endif
#include
+#include /* for memset and strcmp */
#include
#include
#include "pcrecpp.h"
@@ -412,7 +413,7 @@
}
static void TestMatchNumberPeculiarity() {
- printf("Testing match-number peculiaraity\n");
+ printf("Testing match-number peculiarity\n");
string word1;
string word2;
@@ -832,6 +833,7 @@
return 0;
}
+ printf("PCRE C++ wrapper tests\n");
printf("Testing FullMatch\n");
int i;
diff -Nru pcre3-8.12/pcredemo.c pcre3-8.31/pcredemo.c
--- pcre3-8.12/pcredemo.c 2010-11-24 17:38:32.000000000 +0000
+++ pcre3-8.31/pcredemo.c 2012-02-29 08:56:17.000000000 +0000
@@ -248,7 +248,7 @@
* more than one byte. *
* *
* However, there is a complication concerned with newlines. When the *
-* newline convention is such that CRLF is a valid newline, we want must *
+* newline convention is such that CRLF is a valid newline, we must *
* advance by two characters rather than one. The newline convention can *
* be set in the regex by (*CR), etc.; if not, we must find the default. *
*************************************************************************/
diff -Nru pcre3-8.12/pcregrep.c pcre3-8.31/pcregrep.c
--- pcre3-8.12/pcregrep.c 2011-01-15 11:25:12.000000000 +0000
+++ pcre3-8.31/pcregrep.c 2012-06-02 10:55:16.000000000 +0000
@@ -6,7 +6,7 @@
its pattern matching. On a Unix or Win32 system it can recurse into
directories.
- Copyright (c) 1997-2011 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -74,9 +74,9 @@
#define OFFSET_SIZE 99
#if BUFSIZ > 8192
-#define MBUFTHIRD BUFSIZ
+#define PATBUFSIZE BUFSIZ
#else
-#define MBUFTHIRD 8192
+#define PATBUFSIZE 8192
#endif
/* Values for the "filenames" variable, which specifies options for file name
@@ -104,6 +104,10 @@
enum { EL_LF, EL_CR, EL_CRLF, EL_ANY, EL_ANYCRLF };
+/* Binary file options */
+
+enum { BIN_BINARY, BIN_NOMATCH, BIN_TEXT };
+
/* In newer versions of gcc, with FORTIFY_SOURCE set (the default in some
environments), a warning is issued if the value of fwrite() is ignored.
Unfortunately, casting to (void) does not suppress the warning. To get round
@@ -135,6 +139,7 @@
static char *colour_option = NULL;
static char *dee_option = NULL;
static char *DEE_option = NULL;
+static char *main_buffer = NULL;
static char *newline = NULL;
static char *pattern_filename = NULL;
static char *stdin_name = (char *)"(standard input)";
@@ -146,6 +151,7 @@
static pcre **pattern_list = NULL;
static pcre_extra **hints_list = NULL;
+static char *file_list = NULL;
static char *include_pattern = NULL;
static char *exclude_pattern = NULL;
static char *include_dir_pattern = NULL;
@@ -158,7 +164,10 @@
static int after_context = 0;
static int before_context = 0;
+static int binary_files = BIN_BINARY;
static int both_context = 0;
+static int bufthird = PCREGREP_BUFSIZE;
+static int bufsize = 3*PCREGREP_BUFSIZE;
static int dee_action = dee_READ;
static int DEE_action = DEE_READ;
static int error_count = 0;
@@ -166,6 +175,12 @@
static int only_matching = -1;
static int process_options = 0;
+#ifdef SUPPORT_PCREGREP_JIT
+static int study_options = PCRE_STUDY_JIT_COMPILE;
+#else
+static int study_options = 0;
+#endif
+
static unsigned long int match_limit = 0;
static unsigned long int match_limit_recursion = 0;
@@ -187,7 +202,7 @@
/* Structure for options and list of them */
enum { OP_NODATA, OP_STRING, OP_OP_STRING, OP_NUMBER, OP_LONGNUMBER,
- OP_OP_NUMBER, OP_PATLIST };
+ OP_OP_NUMBER, OP_PATLIST, OP_BINFILES };
typedef struct option_item {
int type;
@@ -214,12 +229,19 @@
#define N_LBUFFER (-12)
#define N_M_LIMIT (-13)
#define N_M_LIMIT_REC (-14)
+#define N_BUFSIZE (-15)
+#define N_NOJIT (-16)
+#define N_FILE_LIST (-17)
+#define N_BINARY_FILES (-18)
static option_item optionlist[] = {
- { OP_NODATA, N_NULL, NULL, "", " terminate options" },
+ { OP_NODATA, N_NULL, NULL, "", "terminate options" },
{ OP_NODATA, N_HELP, NULL, "help", "display this help and exit" },
{ OP_NUMBER, 'A', &after_context, "after-context=number", "set number of following context lines" },
+ { OP_NODATA, 'a', NULL, "text", "treat binary files as text" },
{ OP_NUMBER, 'B', &before_context, "before-context=number", "set number of prior context lines" },
+ { OP_BINFILES, N_BINARY_FILES, NULL, "binary-files=word", "set treatment of binary files" },
+ { OP_NUMBER, N_BUFSIZE,&bufthird, "buffer-size=number", "set processing buffer size parameter" },
{ OP_OP_STRING, N_COLOUR, &colour_option, "color=option", "matched text color option" },
{ OP_OP_STRING, N_COLOUR, &colour_option, "colour=option", "matched text colour option" },
{ OP_NUMBER, 'C', &both_context, "context=number", "set number of context lines, before & after" },
@@ -229,10 +251,17 @@
{ OP_PATLIST, 'e', NULL, "regex(p)=pattern", "specify pattern (may be used more than once)" },
{ OP_NODATA, 'F', NULL, "fixed-strings", "patterns are sets of newline-separated strings" },
{ OP_STRING, 'f', &pattern_filename, "file=path", "read patterns from file" },
+ { OP_STRING, N_FILE_LIST, &file_list, "file-list=path","read files to search from file" },
{ OP_NODATA, N_FOFFSETS, NULL, "file-offsets", "output file offsets, not text" },
{ OP_NODATA, 'H', NULL, "with-filename", "force the prefixing filename on output" },
{ OP_NODATA, 'h', NULL, "no-filename", "suppress the prefixing filename on output" },
+ { OP_NODATA, 'I', NULL, "", "treat binary files as not matching (ignore)" },
{ OP_NODATA, 'i', NULL, "ignore-case", "ignore case distinctions" },
+#ifdef SUPPORT_PCREGREP_JIT
+ { OP_NODATA, N_NOJIT, NULL, "no-jit", "do not use just-in-time compiler optimization" },
+#else
+ { OP_NODATA, N_NOJIT, NULL, "no-jit", "ignored: this pcregrep does not support JIT" },
+#endif
{ OP_NODATA, 'l', NULL, "files-with-matches", "print only FILE names containing matches" },
{ OP_NODATA, 'L', NULL, "files-without-match","print only FILE names not containing matches" },
{ OP_STRING, N_LABEL, &stdin_name, "label=name", "set name for standard input" },
@@ -310,8 +339,9 @@
{
if (resource_error)
{
- fprintf(stderr, "pcregrep: Error %d or %d means that a resource limit "
- "was exceeded.\n", PCRE_ERROR_MATCHLIMIT, PCRE_ERROR_RECURSIONLIMIT);
+ fprintf(stderr, "pcregrep: Error %d, %d or %d means that a resource limit "
+ "was exceeded.\n", PCRE_ERROR_MATCHLIMIT, PCRE_ERROR_RECURSIONLIMIT,
+ PCRE_ERROR_JIT_STACKLIMIT);
fprintf(stderr, "pcregrep: Check your regex for nested unlimited loops.\n");
}
@@ -607,7 +637,7 @@
Returns: the number of characters read, zero at end of file
*/
-static int
+static unsigned int
read_one_line(char *buffer, int length, FILE *f)
{
int c;
@@ -634,7 +664,8 @@
endptr end of available data
lenptr where to put the length of the eol sequence
-Returns: pointer to the last byte of the line, including the newline byte(s)
+Returns: pointer after the last byte of the line,
+ including the newline byte(s)
*/
static char *
@@ -935,10 +966,11 @@
to find all possible matches.
Arguments:
- matchptr the start of the subject
- length the length of the subject to match
- offsets the offets vector to fill in
- mrc address of where to put the result of pcre_exec()
+ matchptr the start of the subject
+ length the length of the subject to match
+ startoffset where to start matching
+ offsets the offets vector to fill in
+ mrc address of where to put the result of pcre_exec()
Returns: TRUE if there was a match
FALSE if there was no match
@@ -946,7 +978,8 @@
*/
static BOOL
-match_patterns(char *matchptr, size_t length, int *offsets, int *mrc)
+match_patterns(char *matchptr, size_t length, int startoffset, int *offsets,
+ int *mrc)
{
int i;
size_t slen = length;
@@ -958,8 +991,8 @@
}
for (i = 0; i < pattern_count; i++)
{
- *mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, (int)length, 0,
- PCRE_NOTEMPTY, offsets, OFFSET_SIZE);
+ *mrc = pcre_exec(pattern_list[i], hints_list[i], matchptr, (int)length,
+ startoffset, PCRE_NOTEMPTY, offsets, OFFSET_SIZE);
if (*mrc >= 0) return TRUE;
if (*mrc == PCRE_ERROR_NOMATCH) continue;
fprintf(stderr, "pcregrep: pcre_exec() gave error %d while matching ", *mrc);
@@ -967,7 +1000,8 @@
fprintf(stderr, "%s", msg);
FWRITE(matchptr, 1, slen, stderr); /* In case binary zero included */
fprintf(stderr, "\n\n");
- if (*mrc == PCRE_ERROR_MATCHLIMIT || *mrc == PCRE_ERROR_RECURSIONLIMIT)
+ if (*mrc == PCRE_ERROR_MATCHLIMIT || *mrc == PCRE_ERROR_RECURSIONLIMIT ||
+ *mrc == PCRE_ERROR_JIT_STACKLIMIT)
resource_error = TRUE;
if (error_count++ > 20)
{
@@ -987,7 +1021,7 @@
*************************************************/
/* This is called from grep_or_recurse() below. It uses a buffer that is three
-times the value of MBUFTHIRD. The matching point is never allowed to stray into
+times the value of bufthird. The matching point is never allowed to stray into
the top third of the buffer, thus keeping more of the file available for
context printing or for multiline scanning. For large files, the pointer will
be in the middle third most of the time, so the bottom third is available for
@@ -998,17 +1032,19 @@
the gzFile pointer when reading is via libz
the BZFILE pointer when reading is via libbz2
frtype FR_PLAIN, FR_LIBZ, or FR_LIBBZ2
+ filename the file name or NULL (for errors)
printname the file name if it is to be printed for each match
or NULL if the file name is not to be printed
it cannot be NULL if filenames[_nomatch]_only is set
Returns: 0 if there was at least one match
1 otherwise (no matches)
- 2 if there is a read error on a .bz2 file
+ 2 if an overlong line is encountered
+ 3 if there is a read error on a .bz2 file
*/
static int
-pcregrep(void *handle, int frtype, char *printname)
+pcregrep(void *handle, int frtype, char *filename, char *printname)
{
int rc = 1;
int linenumber = 1;
@@ -1017,10 +1053,10 @@
int filepos = 0;
int offsets[OFFSET_SIZE];
char *lastmatchrestart = NULL;
-char buffer[3*MBUFTHIRD];
-char *ptr = buffer;
+char *ptr = main_buffer;
char *endptr;
size_t bufflength;
+BOOL binary = FALSE;
BOOL endhyphenpending = FALSE;
BOOL input_line_buffered = line_buffered;
FILE *in = NULL; /* Ensure initialized */
@@ -1043,7 +1079,7 @@
if (frtype == FR_LIBZ)
{
ingz = (gzFile)handle;
- bufflength = gzread (ingz, buffer, 3*MBUFTHIRD);
+ bufflength = gzread (ingz, main_buffer, bufsize);
}
else
#endif
@@ -1052,7 +1088,7 @@
if (frtype == FR_LIBBZ2)
{
inbz2 = (BZFILE *)handle;
- bufflength = BZ2_bzread(inbz2, buffer, 3*MBUFTHIRD);
+ bufflength = BZ2_bzread(inbz2, main_buffer, bufsize);
if ((int)bufflength < 0) return 2; /* Gotcha: bufflength is size_t; */
} /* without the cast it is unsigned. */
else
@@ -1062,11 +1098,22 @@
in = (FILE *)handle;
if (is_file_tty(in)) input_line_buffered = TRUE;
bufflength = input_line_buffered?
- read_one_line(buffer, 3*MBUFTHIRD, in) :
- fread(buffer, 1, 3*MBUFTHIRD, in);
+ read_one_line(main_buffer, bufsize, in) :
+ fread(main_buffer, 1, bufsize, in);
}
-endptr = buffer + bufflength;
+endptr = main_buffer + bufflength;
+
+/* Unless binary-files=text, see if we have a binary file. This uses the same
+rule as GNU grep, namely, a search for a binary zero byte near the start of the
+file. */
+
+if (binary_files != BIN_TEXT)
+ {
+ binary =
+ memchr(main_buffer, 0, (bufflength > 1024)? 1024 : bufflength) != NULL;
+ if (binary && binary_files == BIN_NOMATCH) return 1;
+ }
/* Loop while the current pointer is not at the end of the file. For large
files, endptr will be at the end of the buffer when we are in the middle of the
@@ -1077,6 +1124,7 @@
{
int endlinelength;
int mrc = 0;
+ int startoffset = 0;
BOOL match;
char *matchptr = ptr;
char *t = ptr;
@@ -1094,6 +1142,20 @@
linelength = t - ptr - endlinelength;
length = multiline? (size_t)(endptr - ptr) : linelength;
+ /* Check to see if the line we are looking at extends right to the very end
+ of the buffer without a line terminator. This means the line is too long to
+ handle. */
+
+ if (endlinelength == 0 && t == main_buffer + bufsize)
+ {
+ fprintf(stderr, "pcregrep: line %d%s%s is too long for the internal buffer\n"
+ "pcregrep: check the --buffer-size option\n",
+ linenumber,
+ (filename == NULL)? "" : " of file ",
+ (filename == NULL)? "" : filename);
+ return 2;
+ }
+
/* Extra processing for Jeffrey Friedl's debugging. */
#ifdef JFRIEDL_DEBUG
@@ -1153,7 +1215,7 @@
than NOMATCH. This code is in a subroutine so that it can be re-used for
finding subsequent matches when colouring matched lines. */
- match = match_patterns(matchptr, length, offsets, &mrc);
+ match = match_patterns(matchptr, length, startoffset, offsets, &mrc);
/* If it's a match or a not-match (as required), do what's wanted. */
@@ -1169,6 +1231,16 @@
if (count_only) count++;
+ /* When handling a binary file and binary-files==binary, the "binary"
+ variable will be set true (it's false in all other cases). In this
+ situation we just want to output the file name. No need to scan further. */
+
+ else if (binary)
+ {
+ fprintf(stdout, "Binary file %s matches\n", filename);
+ return 0;
+ }
+
/* If all we want is a file name, there is no need to scan any more lines
in the file. */
@@ -1186,10 +1258,10 @@
captured portion of it, as long as this string is not empty, and the
--file-offsets and --line-offsets options output offsets for the matching
substring (they both force --only-matching = 0). None of these options
- prints any context. Afterwards, adjust the start and length, and then jump
- back to look for further matches in the same line. If we are in invert
- mode, however, nothing is printed and we do not restart - this could still
- be useful because the return code is set. */
+ prints any context. Afterwards, adjust the start and then jump back to look
+ for further matches in the same line. If we are in invert mode, however,
+ nothing is printed and we do not restart - this could still be useful
+ because the return code is set. */
else if (only_matching >= 0)
{
@@ -1216,11 +1288,10 @@
}
}
else if (printname != NULL || number) fprintf(stdout, "\n");
- matchptr += offsets[1];
- length -= offsets[1];
match = FALSE;
if (line_buffered) fflush(stdout);
- rc = 0; /* Had some success */
+ rc = 0; /* Had some success */
+ startoffset = offsets[1]; /* Restart after the match */
goto ONLY_MATCHING_RESTART;
}
}
@@ -1279,11 +1350,11 @@
int linecount = 0;
char *p = ptr;
- while (p > buffer && (lastmatchnumber == 0 || p > lastmatchrestart) &&
+ while (p > main_buffer && (lastmatchnumber == 0 || p > lastmatchrestart) &&
linecount < before_context)
{
linecount++;
- p = previous_line(p, buffer);
+ p = previous_line(p, main_buffer);
}
if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted)
@@ -1353,19 +1424,17 @@
if (do_colour && !invert)
{
int plength;
- int last_offset = 0;
FWRITE(ptr, 1, offsets[0], stdout);
fprintf(stdout, "%c[%sm", 0x1b, colour_string);
FWRITE(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
fprintf(stdout, "%c[00m", 0x1b);
for (;;)
{
- last_offset += offsets[1];
- matchptr += offsets[1];
- length -= offsets[1];
- if (last_offset >= linelength + endlinelength ||
- !match_patterns(matchptr, length, offsets, &mrc)) break;
- FWRITE(matchptr, 1, offsets[0], stdout);
+ startoffset = offsets[1];
+ if (startoffset >= (int)linelength + endlinelength ||
+ !match_patterns(matchptr, length, startoffset, offsets, &mrc))
+ break;
+ FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout);
fprintf(stdout, "%c[%sm", 0x1b, colour_string);
FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
fprintf(stdout, "%c[00m", 0x1b);
@@ -1375,9 +1444,8 @@
and its line-ending characters (if they matched the pattern), so there
may be no more to print. */
- plength = (linelength + endlinelength) - last_offset;
- if (plength > 0)
- FWRITE(ptr + last_offset, 1, plength, stdout);
+ plength = (int)((linelength + endlinelength) - startoffset);
+ if (plength > 0) FWRITE(ptr + startoffset, 1, plength, stdout);
}
/* Not colouring; no need to search for further matches */
@@ -1426,9 +1494,9 @@
/* If input is line buffered, and the buffer is not yet full, read another
line and add it into the buffer. */
- if (input_line_buffered && bufflength < sizeof(buffer))
+ if (input_line_buffered && bufflength < (size_t)bufsize)
{
- int add = read_one_line(ptr, sizeof(buffer) - (ptr - buffer), in);
+ int add = read_one_line(ptr, bufsize - (int)(ptr - main_buffer), in);
bufflength += add;
endptr += add;
}
@@ -1438,11 +1506,11 @@
1/3 and refill it. Before we do this, if some unprinted "after" lines are
about to be lost, print them. */
- if (bufflength >= sizeof(buffer) && ptr > buffer + 2*MBUFTHIRD)
+ if (bufflength >= (size_t)bufsize && ptr > main_buffer + 2*bufthird)
{
if (after_context > 0 &&
lastmatchnumber > 0 &&
- lastmatchrestart < buffer + MBUFTHIRD)
+ lastmatchrestart < main_buffer + bufthird)
{
do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname);
lastmatchnumber = 0;
@@ -1450,32 +1518,32 @@
/* Now do the shuffle */
- memmove(buffer, buffer + MBUFTHIRD, 2*MBUFTHIRD);
- ptr -= MBUFTHIRD;
+ memmove(main_buffer, main_buffer + bufthird, 2*bufthird);
+ ptr -= bufthird;
#ifdef SUPPORT_LIBZ
if (frtype == FR_LIBZ)
- bufflength = 2*MBUFTHIRD +
- gzread (ingz, buffer + 2*MBUFTHIRD, MBUFTHIRD);
+ bufflength = 2*bufthird +
+ gzread (ingz, main_buffer + 2*bufthird, bufthird);
else
#endif
#ifdef SUPPORT_LIBBZ2
if (frtype == FR_LIBBZ2)
- bufflength = 2*MBUFTHIRD +
- BZ2_bzread(inbz2, buffer + 2*MBUFTHIRD, MBUFTHIRD);
+ bufflength = 2*bufthird +
+ BZ2_bzread(inbz2, main_buffer + 2*bufthird, bufthird);
else
#endif
- bufflength = 2*MBUFTHIRD +
+ bufflength = 2*bufthird +
(input_line_buffered?
- read_one_line(buffer + 2*MBUFTHIRD, MBUFTHIRD, in) :
- fread(buffer + 2*MBUFTHIRD, 1, MBUFTHIRD, in));
- endptr = buffer + bufflength;
+ read_one_line(main_buffer + 2*bufthird, bufthird, in) :
+ fread(main_buffer + 2*bufthird, 1, bufthird, in));
+ endptr = main_buffer + bufflength;
/* Adjust any last match point */
- if (lastmatchnumber > 0) lastmatchrestart -= MBUFTHIRD;
+ if (lastmatchnumber > 0) lastmatchrestart -= bufthird;
}
} /* Loop through the whole file */
@@ -1539,7 +1607,6 @@
int rc = 1;
int sep;
int frtype;
-int pathlen;
void *handle;
FILE *in = NULL; /* Ensure initialized */
@@ -1551,11 +1618,15 @@
BZFILE *inbz2 = NULL;
#endif
+#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2
+int pathlen;
+#endif
+
/* If the file name is "-" we scan stdin */
if (strcmp(pathname, "-") == 0)
{
- return pcregrep(stdin, FR_PLAIN,
+ return pcregrep(stdin, FR_PLAIN, stdin_name,
(filenames > FN_DEFAULT || (filenames == FN_DEFAULT && !only_one_at_top))?
stdin_name : NULL);
}
@@ -1630,7 +1701,9 @@
argument at top level, we don't show the file name, unless we are only showing
the file name, or the filename was forced (-H). */
+#if defined SUPPORT_LIBZ || defined SUPPORT_LIBBZ2
pathlen = (int)(strlen(pathname));
+#endif
/* Open using zlib if it is supported and the file name ends with .gz. */
@@ -1687,7 +1760,7 @@
/* Now grep the file */
-rc = pcregrep(handle, frtype, (filenames > FN_DEFAULT ||
+rc = pcregrep(handle, frtype, pathname, (filenames > FN_DEFAULT ||
(filenames == FN_DEFAULT && !only_one_at_top))? pathname : NULL);
/* Close in an appropriate manner. */
@@ -1698,14 +1771,14 @@
else
#endif
-/* If it is a .bz2 file and the result is 2, it means that the first attempt to
+/* If it is a .bz2 file and the result is 3, it means that the first attempt to
read failed. If the error indicates that the file isn't in fact bzipped, try
again as a normal file. */
#ifdef SUPPORT_LIBBZ2
if (frtype == FR_LIBBZ2)
{
- if (rc == 2)
+ if (rc == 3)
{
int errnum;
const char *err = BZ2_bzerror(inbz2, &errnum);
@@ -1717,6 +1790,7 @@
else if (!silent)
fprintf(stderr, "pcregrep: Failed to read %s using bzlib: %s\n",
pathname, err);
+ rc = 2; /* The normal "something went wrong" code */
}
BZ2_bzclose(inbz2);
}
@@ -1803,15 +1877,25 @@
if (strchr(op->long_name, '_') != NULL) continue;
- if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, " ");
- n = 31 - printf(" %s --%s", s, op->long_name);
+ if (op->one_char > 0 && (op->long_name)[0] == 0)
+ n = 31 - printf(" -%c", op->one_char);
+ else
+ {
+ if (op->one_char > 0) sprintf(s, "-%c,", op->one_char);
+ else strcpy(s, " ");
+ n = 31 - printf(" %s --%s", s, op->long_name);
+ }
+
if (n < 1) n = 1;
- printf("%.*s%s\n", n, " ", op->help_text);
+ printf("%.*s%s\n", n, " ", op->help_text);
}
-printf("\nWhen reading patterns from a file instead of using a command line option,\n");
-printf("trailing white space is removed and blank lines are ignored.\n");
-printf("There is a maximum of %d patterns.\n", MAX_PATTERN_COUNT);
+printf("\nNumbers may be followed by K or M, e.g. --buffer-size=100K.\n");
+printf("The default value for --buffer-size is %d.\n", PCREGREP_BUFSIZE);
+printf("When reading patterns or file names from a file, trailing white\n");
+printf("space is removed and blank lines are ignored.\n");
+printf("There is a maximum of %d patterns, each of maximum size %d bytes.\n",
+ MAX_PATTERN_COUNT, PATBUFSIZE);
printf("\nWith no FILEs, read standard input. If fewer than two FILEs given, assume -h.\n");
printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n");
@@ -1831,11 +1915,14 @@
{
case N_FOFFSETS: file_offsets = TRUE; break;
case N_HELP: help(); pcregrep_exit(0);
- case N_LOFFSETS: line_offsets = number = TRUE; break;
case N_LBUFFER: line_buffered = TRUE; break;
+ case N_LOFFSETS: line_offsets = number = TRUE; break;
+ case N_NOJIT: study_options &= ~PCRE_STUDY_JIT_COMPILE; break;
+ case 'a': binary_files = BIN_TEXT; break;
case 'c': count_only = TRUE; break;
case 'F': process_options |= PO_FIXED_STRINGS; break;
case 'H': filenames = FN_FORCE; break;
+ case 'I': binary_files = BIN_NOMATCH; break;
case 'h': filenames = FN_NONE; break;
case 'i': options |= PCRE_CASELESS; break;
case 'l': omit_zero_count = TRUE; filenames = FN_MATCH_ONLY; break;
@@ -1913,7 +2000,7 @@
static BOOL
compile_single_pattern(char *pattern, int options, char *filename, int count)
{
-char buffer[MBUFTHIRD + 16];
+char buffer[PATBUFSIZE];
const char *error;
int errptr;
@@ -1924,7 +2011,7 @@
return FALSE;
}
-sprintf(buffer, "%s%.*s%s", prefix[process_options], MBUFTHIRD, pattern,
+sprintf(buffer, "%s%.*s%s", prefix[process_options], bufthird, pattern,
suffix[process_options]);
pattern_list[pattern_count] =
pcre_compile(buffer, options, &error, &errptr, pcretables);
@@ -1983,7 +2070,7 @@
if ((process_options & PO_FIXED_STRINGS) != 0)
{
char *eop = pattern + strlen(pattern);
- char buffer[MBUFTHIRD];
+ char buffer[PATBUFSIZE];
for(;;)
{
int ellength;
@@ -2021,6 +2108,10 @@
const char *locale_from = "--locale";
const char *error;
+#ifdef SUPPORT_PCREGREP_JIT
+pcre_jit_stack *jit_stack = NULL;
+#endif
+
/* Set the default line ending value from the default in the PCRE library;
"lf", "cr", "crlf", and "any" are supported. Anything else is treated as "lf".
Note that the return values from pcre_config(), though derived from the ASCII
@@ -2277,6 +2368,24 @@
patterns[cmd_pattern_count++] = option_data;
}
+ /* Handle OP_BINARY_FILES */
+
+ else if (op->type == OP_BINFILES)
+ {
+ if (strcmp(option_data, "binary") == 0)
+ binary_files = BIN_BINARY;
+ else if (strcmp(option_data, "without-match") == 0)
+ binary_files = BIN_NOMATCH;
+ else if (strcmp(option_data, "text") == 0)
+ binary_files = BIN_TEXT;
+ else
+ {
+ fprintf(stderr, "pcregrep: unknown value \"%s\" for binary-files\n",
+ option_data);
+ pcregrep_exit(usage(2));
+ }
+ }
+
/* Otherwise, deal with single string or numeric data values. */
else if (op->type != OP_NUMBER && op->type != OP_LONGNUMBER &&
@@ -2295,6 +2404,16 @@
while (*endptr != 0 && isspace((unsigned char)(*endptr))) endptr++;
while (isdigit((unsigned char)(*endptr)))
n = n * 10 + (int)(*endptr++ - '0');
+ if (toupper(*endptr) == 'K')
+ {
+ n *= 1024;
+ endptr++;
+ }
+ else if (toupper(*endptr) == 'M')
+ {
+ n *= 1024*1024;
+ endptr++;
+ }
if (*endptr != 0)
{
if (longop)
@@ -2461,12 +2580,14 @@
}
#endif
-/* Get memory to store the pattern and hints lists. */
+/* Get memory for the main buffer, and to store the pattern and hints lists. */
+bufsize = 3*bufthird;
+main_buffer = (char *)malloc(bufsize);
pattern_list = (pcre **)malloc(MAX_PATTERN_COUNT * sizeof(pcre *));
hints_list = (pcre_extra **)malloc(MAX_PATTERN_COUNT * sizeof(pcre_extra *));
-if (pattern_list == NULL || hints_list == NULL)
+if (main_buffer == NULL || pattern_list == NULL || hints_list == NULL)
{
fprintf(stderr, "pcregrep: malloc failed\n");
goto EXIT2;
@@ -2498,7 +2619,7 @@
int linenumber = 0;
FILE *f;
char *filename;
- char buffer[MBUFTHIRD];
+ char buffer[PATBUFSIZE];
if (strcmp(pattern_filename, "-") == 0)
{
@@ -2517,7 +2638,7 @@
filename = pattern_filename;
}
- while (fgets(buffer, MBUFTHIRD, f) != NULL)
+ while (fgets(buffer, PATBUFSIZE, f) != NULL)
{
char *s = buffer + (int)strlen(buffer);
while (s > buffer && isspace((unsigned char)(s[-1]))) s--;
@@ -2531,11 +2652,17 @@
if (f != stdin) fclose(f);
}
-/* Study the regular expressions, as we will be running them many times */
+/* Study the regular expressions, as we will be running them many times. Unless
+JIT has been explicitly disabled, arrange a stack for it to use. */
+
+#ifdef SUPPORT_PCREGREP_JIT
+if ((study_options & PCRE_STUDY_JIT_COMPILE) != 0)
+ jit_stack = pcre_jit_stack_alloc(32*1024, 1024*1024);
+#endif
for (j = 0; j < pattern_count; j++)
{
- hints_list[j] = pcre_study(pattern_list[j], 0, &error);
+ hints_list[j] = pcre_study(pattern_list[j], study_options, &error);
if (error != NULL)
{
char s[16];
@@ -2544,6 +2671,10 @@
goto EXIT2;
}
hint_count++;
+#ifdef SUPPORT_PCREGREP_JIT
+ if (jit_stack != NULL && hints_list[j] != NULL)
+ pcre_assign_jit_stack(hints_list[j], NULL, jit_stack);
+#endif
}
/* If --match-limit or --recursion-limit was set, put the value(s) into the
@@ -2625,20 +2756,55 @@
}
}
-/* If there are no further arguments, do the business on stdin and exit. */
+/* If a file that contains a list of files to search has been specified, read
+it line by line and search the given files. Otherwise, if there are no further
+arguments, do the business on stdin and exit. */
-if (i >= argc)
+if (file_list != NULL)
{
- rc = pcregrep(stdin, FR_PLAIN, (filenames > FN_DEFAULT)? stdin_name : NULL);
+ char buffer[PATBUFSIZE];
+ FILE *fl;
+ if (strcmp(file_list, "-") == 0) fl = stdin; else
+ {
+ fl = fopen(file_list, "rb");
+ if (fl == NULL)
+ {
+ fprintf(stderr, "pcregrep: Failed to open %s: %s\n", file_list,
+ strerror(errno));
+ goto EXIT2;
+ }
+ }
+ while (fgets(buffer, PATBUFSIZE, fl) != NULL)
+ {
+ int frc;
+ char *end = buffer + (int)strlen(buffer);
+ while (end > buffer && isspace(end[-1])) end--;
+ *end = 0;
+ if (*buffer != 0)
+ {
+ frc = grep_or_recurse(buffer, dee_action == dee_RECURSE, FALSE);
+ if (frc > 1) rc = frc;
+ else if (frc == 0 && rc == 1) rc = 0;
+ }
+ }
+ if (fl != stdin) fclose (fl);
+ }
+
+/* Do this only if there was no file list (and no file arguments). */
+
+else if (i >= argc)
+ {
+ rc = pcregrep(stdin, FR_PLAIN, stdin_name,
+ (filenames > FN_DEFAULT)? stdin_name : NULL);
goto EXIT;
}
-/* Otherwise, work through the remaining arguments as files or directories.
-Pass in the fact that there is only one argument at top level - this suppresses
-the file name if the argument is not a directory and filenames are not
-otherwise forced. */
+/* After handling file-list or if there are remaining arguments, work through
+them as files or directories. Pass in the fact that there is only one argument
+at top level - this suppresses the file name if the argument is not a directory
+and filenames are not otherwise forced. */
-only_one_at_top = i == argc - 1; /* Catch initial value of i */
+only_one_at_top = i == argc - 1 && file_list == NULL;
for (; i < argc; i++)
{
@@ -2649,6 +2815,10 @@
}
EXIT:
+#ifdef SUPPORT_PCREGREP_JIT
+if (jit_stack != NULL) pcre_jit_stack_free(jit_stack);
+#endif
+if (main_buffer != NULL) free(main_buffer);
if (pattern_list != NULL)
{
for (i = 0; i < pattern_count; i++) free(pattern_list[i]);
@@ -2658,7 +2828,7 @@
{
for (i = 0; i < hint_count; i++)
{
- if (hints_list[i] != NULL) free(hints_list[i]);
+ if (hints_list[i] != NULL) pcre_free_study(hints_list[i]);
}
free(hints_list);
}
diff -Nru pcre3-8.12/pcreposix.c pcre3-8.31/pcreposix.c
--- pcre3-8.12/pcreposix.c 2010-11-24 17:38:32.000000000 +0000
+++ pcre3-8.31/pcreposix.c 2012-06-20 15:08:49.000000000 +0000
@@ -6,7 +6,7 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
- Copyright (c) 1997-2010 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -152,6 +152,16 @@
REG_BADPAT, /* (*MARK) must have an argument */
REG_INVARG, /* this version of PCRE is not compiled with PCRE_UCP support */
REG_BADPAT, /* \c must be followed by an ASCII character */
+ REG_BADPAT, /* \k is not followed by a braced, angle-bracketed, or quoted name */
+ /* 70 */
+ REG_BADPAT, /* internal error: unknown opcode in find_fixedlength() */
+ REG_BADPAT, /* \N is not supported in a class */
+ REG_BADPAT, /* too many forward references */
+ REG_BADPAT, /* disallowed UTF-8/16 code point (>= 0xd800 && <= 0xdfff) */
+ REG_BADPAT, /* invalid UTF-16 string (should not occur) */
+ /* 75 */
+ REG_BADPAT, /* overlong MARK name */
+ REG_BADPAT /* character value in \u.... sequence is too large */
};
/* Table of texts corresponding to POSIX error codes */
@@ -222,7 +232,7 @@
PCREPOSIX_EXP_DEFN void PCRE_CALL_CONVENTION
regfree(regex_t *preg)
{
-(pcre_free)(preg->re_pcre);
+(PUBL(free))(preg->re_pcre);
}
@@ -267,11 +277,12 @@
if (preg->re_pcre == NULL)
{
- return (errorcode < sizeof(eint)/sizeof(const int))?
+ return (errorcode < (int)(sizeof(eint)/sizeof(const int)))?
eint[errorcode] : REG_BADPAT;
}
-preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL);
+(void)pcre_fullinfo((const pcre *)preg->re_pcre, NULL, PCRE_INFO_CAPTURECOUNT,
+ &(preg->re_nsub));
return 0;
}
@@ -397,6 +408,7 @@
case PCRE_ERROR_MATCHLIMIT: return REG_ESPACE;
case PCRE_ERROR_BADUTF8: return REG_INVARG;
case PCRE_ERROR_BADUTF8_OFFSET: return REG_INVARG;
+ case PCRE_ERROR_BADMODE: return REG_INVARG;
default: return REG_ASSERT;
}
}
diff -Nru pcre3-8.12/pcreposix.h pcre3-8.31/pcreposix.h
--- pcre3-8.12/pcreposix.h 2013-03-27 06:36:17.000000000 +0000
+++ pcre3-8.31/pcreposix.h 2011-12-28 16:57:51.000000000 +0000
@@ -9,7 +9,7 @@
Compatible Regular Expression library. It defines the things POSIX says should
be there. I hope.
- Copyright (c) 1997-2009 University of Cambridge
+ Copyright (c) 1997-2012 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -133,19 +133,14 @@
/* The functions */
-PCREPOSIX_EXP_DECL int pcreposix_regcomp(regex_t *, const char *, int);
-PCREPOSIX_EXP_DECL int pcreposix_regexec(const regex_t *, const char *, size_t,
+PCREPOSIX_EXP_DECL int regcomp(regex_t *, const char *, int);
+PCREPOSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t,
regmatch_t *, int);
-PCREPOSIX_EXP_DECL size_t pcreposix_regerror(int, const regex_t *, char *, size_t);
-PCREPOSIX_EXP_DECL void pcreposix_regfree(regex_t *);
+PCREPOSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t);
+PCREPOSIX_EXP_DECL void regfree(regex_t *);
#ifdef __cplusplus
} /* extern "C" */
#endif
-#define regcomp pcreposix_regcomp
-#define regexec pcreposix_regexec
-#define regerror pcreposix_regerror
-#define regfree pcreposix_regfree
-
#endif /* End of pcreposix.h */
diff -Nru pcre3-8.12/pcretest.c pcre3-8.31/pcretest.c
--- pcre3-8.12/pcretest.c 2013-03-27 06:36:17.000000000 +0000
+++ pcre3-8.31/pcretest.c 2012-06-02 10:55:16.000000000 +0000
@@ -4,7 +4,8 @@
/* This program was hacked up as a tester for PCRE. I really should have
written it more tidily in the first place. Will I ever learn? It has grown and
-been extended and consequently is now rather, er, *very* untidy in places.
+been extended and consequently is now rather, er, *very* untidy in places. The
+addition of 16-bit support has made it even worse. :-(
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -35,6 +36,15 @@
-----------------------------------------------------------------------------
*/
+/* This program now supports the testing of both the 8-bit and 16-bit PCRE
+libraries in a single program. This is different from the modules such as
+pcre_compile.c in the library itself, which are compiled separately for each
+mode. If both modes are enabled, for example, pcre_compile.c is compiled twice
+(the second time with COMPILE_PCRE16 defined). By contrast, pcretest.c is
+compiled only once. Therefore, it must not make use of any of the macros from
+pcre_internal.h that depend on COMPILE_PCRE8 or COMPILE_PCRE16. It does,
+however, make use of SUPPORT_PCRE8 and SUPPORT_PCRE16 to ensure that it calls
+only supported library functions. */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -48,14 +58,26 @@
#include
#include
-#ifdef SUPPORT_LIBREADLINE
+/* Both libreadline and libedit are optionally supported. The user-supplied
+original patch uses readline/readline.h for libedit, but in at least one system
+it is installed as editline/readline.h, so the configuration code now looks for
+that first, falling back to readline/readline.h. */
+
+#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
#ifdef HAVE_UNISTD_H
#include
#endif
+#if defined(SUPPORT_LIBREADLINE)
#include
#include
+#else
+#if defined(HAVE_EDITLINE_READLINE_H)
+#include
+#else
+#include
+#endif
+#endif
#endif
-
/* A number of things vary for Windows builds. Originally, pcretest opened its
input and output without "b"; then I was told that "b" was needed in some
@@ -94,6 +116,7 @@
#define OUTPUT_MODE "wb"
#endif
+#define PRIV(name) name
/* We have to include pcre_internal.h because we need the internal info for
displaying the results of pcre_study() and we also need to know about the
@@ -105,40 +128,52 @@
appropriately for an application, not for building PCRE. */
#include "pcre.h"
+
+#if defined SUPPORT_PCRE16 && !defined SUPPORT_PCRE8
+/* Configure internal macros to 16 bit mode. */
+#define COMPILE_PCRE16
+#endif
+
#include "pcre_internal.h"
+/* The pcre_printint() function, which prints the internal form of a compiled
+regex, is held in a separate file so that (a) it can be compiled in either
+8-bit or 16-bit mode, and (b) it can be #included directly in pcre_compile.c
+when that is compiled in debug mode. */
+
+#ifdef SUPPORT_PCRE8
+void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths);
+#endif
+#ifdef SUPPORT_PCRE16
+void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths);
+#endif
+
/* We need access to some of the data tables that PCRE uses. So as not to have
to keep two copies, we include the source file here, changing the names of the
external symbols to prevent clashes. */
-#define _pcre_ucp_gentype ucp_gentype
-#define _pcre_utf8_table1 utf8_table1
-#define _pcre_utf8_table1_size utf8_table1_size
-#define _pcre_utf8_table2 utf8_table2
-#define _pcre_utf8_table3 utf8_table3
-#define _pcre_utf8_table4 utf8_table4
-#define _pcre_utt utt
-#define _pcre_utt_size utt_size
-#define _pcre_utt_names utt_names
-#define _pcre_OP_lengths OP_lengths
+#define PCRE_INCLUDED
#include "pcre_tables.c"
-/* We also need the pcre_printint() function for printing out compiled
-patterns. This function is in a separate file so that it can be included in
-pcre_compile.c when that module is compiled with debugging enabled. It needs to
-know which case is being compiled. */
-
-#define COMPILING_PCRETEST
-#include "pcre_printint.src"
-
/* The definition of the macro PRINTABLE, which determines whether to print an
output character as-is or as a hex value when showing compiled patterns, is
-contained in the printint.src file. We uses it here also, in cases when the
-locale has not been explicitly changed, so as to get consistent output from
-systems that differ in their output from isprint() even in the "C" locale. */
+the same as in the printint.src file. We uses it here in cases when the locale
+has not been explicitly changed, so as to get consistent output from systems
+that differ in their output from isprint() even in the "C" locale. */
-#define PRINTHEX(c) (locale_set? isprint(c) : PRINTABLE(c))
+#ifdef EBCDIC
+#define PRINTABLE(c) ((c) >= 64 && (c) < 255)
+#else
+#define PRINTABLE(c) ((c) >= 32 && (c) < 127)
+#endif
+
+#define PRINTOK(c) (locale_set? isprint(c) : PRINTABLE(c))
+
+/* Posix support is disabled in 16 bit only mode. */
+#if defined SUPPORT_PCRE16 && !defined SUPPORT_PCRE8 && !defined NOPOSIX
+#define NOPOSIX
+#endif
/* It is possible to compile this test program without including support for
testing the POSIX interface, though this is not available via the standard
@@ -148,18 +183,422 @@
#include "pcreposix.h"
#endif
-/* It is also possible, for the benefit of the version currently imported into
-Exim, to build pcretest without support for UTF8 (define NOUTF8), without the
-interface to the DFA matcher (NODFA), and without the doublecheck of the old
-"info" function (define NOINFOCHECK). In fact, we automatically cut out the
-UTF8 support if PCRE is built without it. */
-
-#ifndef SUPPORT_UTF8
-#ifndef NOUTF8
-#define NOUTF8
+/* It is also possible, originally for the benefit of a version that was
+imported into Exim, to build pcretest without support for UTF8 or UTF16 (define
+NOUTF), without the interface to the DFA matcher (NODFA). In fact, we
+automatically cut out the UTF support if PCRE is built without it. */
+
+#ifndef SUPPORT_UTF
+#ifndef NOUTF
+#define NOUTF
#endif
#endif
+/* To make the code a bit tidier for 8-bit and 16-bit support, we define macros
+for all the pcre[16]_xxx functions (except pcre16_fullinfo, which is called
+only from one place and is handled differently). I couldn't dream up any way of
+using a single macro to do this in a generic way, because of the many different
+argument requirements. We know that at least one of SUPPORT_PCRE8 and
+SUPPORT_PCRE16 must be set. First define macros for each individual mode; then
+use these in the definitions of generic macros.
+
+**** Special note about the PCHARSxxx macros: the address of the string to be
+printed is always given as two arguments: a base address followed by an offset.
+The base address is cast to the correct data size for 8 or 16 bit data; the
+offset is in units of this size. If the string were given as base+offset in one
+argument, the casting might be incorrectly applied. */
+
+#ifdef SUPPORT_PCRE8
+
+#define PCHARS8(lv, p, offset, len, f) \
+ lv = pchars((pcre_uint8 *)(p) + offset, len, f)
+
+#define PCHARSV8(p, offset, len, f) \
+ (void)pchars((pcre_uint8 *)(p) + offset, len, f)
+
+#define READ_CAPTURE_NAME8(p, cn8, cn16, re) \
+ p = read_capture_name8(p, cn8, re)
+
+#define STRLEN8(p) ((int)strlen((char *)p))
+
+#define SET_PCRE_CALLOUT8(callout) \
+ pcre_callout = callout
+
+#define PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata) \
+ pcre_assign_jit_stack(extra, callback, userdata)
+
+#define PCRE_COMPILE8(re, pat, options, error, erroffset, tables) \
+ re = pcre_compile((char *)pat, options, error, erroffset, tables)
+
+#define PCRE_COPY_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
+ namesptr, cbuffer, size) \
+ rc = pcre_copy_named_substring(re, (char *)bptr, offsets, count, \
+ (char *)namesptr, cbuffer, size)
+
+#define PCRE_COPY_SUBSTRING8(rc, bptr, offsets, count, i, cbuffer, size) \
+ rc = pcre_copy_substring((char *)bptr, offsets, count, i, cbuffer, size)
+
+#define PCRE_DFA_EXEC8(count, re, extra, bptr, len, start_offset, options, \
+ offsets, size_offsets, workspace, size_workspace) \
+ count = pcre_dfa_exec(re, extra, (char *)bptr, len, start_offset, options, \
+ offsets, size_offsets, workspace, size_workspace)
+
+#define PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
+ offsets, size_offsets) \
+ count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options, \
+ offsets, size_offsets)
+
+#define PCRE_FREE_STUDY8(extra) \
+ pcre_free_study(extra)
+
+#define PCRE_FREE_SUBSTRING8(substring) \
+ pcre_free_substring(substring)
+
+#define PCRE_FREE_SUBSTRING_LIST8(listptr) \
+ pcre_free_substring_list(listptr)
+
+#define PCRE_GET_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
+ getnamesptr, subsptr) \
+ rc = pcre_get_named_substring(re, (char *)bptr, offsets, count, \
+ (char *)getnamesptr, subsptr)
+
+#define PCRE_GET_STRINGNUMBER8(n, rc, ptr) \
+ n = pcre_get_stringnumber(re, (char *)ptr)
+
+#define PCRE_GET_SUBSTRING8(rc, bptr, offsets, count, i, subsptr) \
+ rc = pcre_get_substring((char *)bptr, offsets, count, i, subsptr)
+
+#define PCRE_GET_SUBSTRING_LIST8(rc, bptr, offsets, count, listptr) \
+ rc = pcre_get_substring_list((const char *)bptr, offsets, count, listptr)
+
+#define PCRE_PATTERN_TO_HOST_BYTE_ORDER8(rc, re, extra, tables) \
+ rc = pcre_pattern_to_host_byte_order(re, extra, tables)
+
+#define PCRE_PRINTINT8(re, outfile, debug_lengths) \
+ pcre_printint(re, outfile, debug_lengths)
+
+#define PCRE_STUDY8(extra, re, options, error) \
+ extra = pcre_study(re, options, error)
+
+#define PCRE_JIT_STACK_ALLOC8(startsize, maxsize) \
+ pcre_jit_stack_alloc(startsize, maxsize)
+
+#define PCRE_JIT_STACK_FREE8(stack) \
+ pcre_jit_stack_free(stack)
+
+#endif /* SUPPORT_PCRE8 */
+
+/* -----------------------------------------------------------*/
+
+#ifdef SUPPORT_PCRE16
+
+#define PCHARS16(lv, p, offset, len, f) \
+ lv = pchars16((PCRE_SPTR16)(p) + offset, len, f)
+
+#define PCHARSV16(p, offset, len, f) \
+ (void)pchars16((PCRE_SPTR16)(p) + offset, len, f)
+
+#define READ_CAPTURE_NAME16(p, cn8, cn16, re) \
+ p = read_capture_name16(p, cn16, re)
+
+#define STRLEN16(p) ((int)strlen16((PCRE_SPTR16)p))
+
+#define SET_PCRE_CALLOUT16(callout) \
+ pcre16_callout = (int (*)(pcre16_callout_block *))callout
+
+#define PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata) \
+ pcre16_assign_jit_stack((pcre16_extra *)extra, \
+ (pcre16_jit_callback)callback, userdata)
+
+#define PCRE_COMPILE16(re, pat, options, error, erroffset, tables) \
+ re = (pcre *)pcre16_compile((PCRE_SPTR16)pat, options, error, erroffset, \
+ tables)
+
+#define PCRE_COPY_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
+ namesptr, cbuffer, size) \
+ rc = pcre16_copy_named_substring((pcre16 *)re, (PCRE_SPTR16)bptr, offsets, \
+ count, (PCRE_SPTR16)namesptr, (PCRE_UCHAR16 *)cbuffer, size/2)
+
+#define PCRE_COPY_SUBSTRING16(rc, bptr, offsets, count, i, cbuffer, size) \
+ rc = pcre16_copy_substring((PCRE_SPTR16)bptr, offsets, count, i, \
+ (PCRE_UCHAR16 *)cbuffer, size/2)
+
+#define PCRE_DFA_EXEC16(count, re, extra, bptr, len, start_offset, options, \
+ offsets, size_offsets, workspace, size_workspace) \
+ count = pcre16_dfa_exec((pcre16 *)re, (pcre16_extra *)extra, \
+ (PCRE_SPTR16)bptr, len, start_offset, options, offsets, size_offsets, \
+ workspace, size_workspace)
+
+#define PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
+ offsets, size_offsets) \
+ count = pcre16_exec((pcre16 *)re, (pcre16_extra *)extra, (PCRE_SPTR16)bptr, \
+ len, start_offset, options, offsets, size_offsets)
+
+#define PCRE_FREE_STUDY16(extra) \
+ pcre16_free_study((pcre16_extra *)extra)
+
+#define PCRE_FREE_SUBSTRING16(substring) \
+ pcre16_free_substring((PCRE_SPTR16)substring)
+
+#define PCRE_FREE_SUBSTRING_LIST16(listptr) \
+ pcre16_free_substring_list((PCRE_SPTR16 *)listptr)
+
+#define PCRE_GET_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
+ getnamesptr, subsptr) \
+ rc = pcre16_get_named_substring((pcre16 *)re, (PCRE_SPTR16)bptr, offsets, \
+ count, (PCRE_SPTR16)getnamesptr, (PCRE_SPTR16 *)(void*)subsptr)
+
+#define PCRE_GET_STRINGNUMBER16(n, rc, ptr) \
+ n = pcre16_get_stringnumber(re, (PCRE_SPTR16)ptr)
+
+#define PCRE_GET_SUBSTRING16(rc, bptr, offsets, count, i, subsptr) \
+ rc = pcre16_get_substring((PCRE_SPTR16)bptr, offsets, count, i, \
+ (PCRE_SPTR16 *)(void*)subsptr)
+
+#define PCRE_GET_SUBSTRING_LIST16(rc, bptr, offsets, count, listptr) \
+ rc = pcre16_get_substring_list((PCRE_SPTR16)bptr, offsets, count, \
+ (PCRE_SPTR16 **)(void*)listptr)
+
+#define PCRE_PATTERN_TO_HOST_BYTE_ORDER16(rc, re, extra, tables) \
+ rc = pcre16_pattern_to_host_byte_order((pcre16 *)re, (pcre16_extra *)extra, \
+ tables)
+
+#define PCRE_PRINTINT16(re, outfile, debug_lengths) \
+ pcre16_printint(re, outfile, debug_lengths)
+
+#define PCRE_STUDY16(extra, re, options, error) \
+ extra = (pcre_extra *)pcre16_study((pcre16 *)re, options, error)
+
+#define PCRE_JIT_STACK_ALLOC16(startsize, maxsize) \
+ (pcre_jit_stack *)pcre16_jit_stack_alloc(startsize, maxsize)
+
+#define PCRE_JIT_STACK_FREE16(stack) \
+ pcre16_jit_stack_free((pcre16_jit_stack *)stack)
+
+#endif /* SUPPORT_PCRE16 */
+
+
+/* ----- Both modes are supported; a runtime test is needed, except for
+pcre_config(), and the JIT stack functions, when it doesn't matter which
+version is called. ----- */
+
+#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
+
+#define CHAR_SIZE (use_pcre16? 2:1)
+
+#define PCHARS(lv, p, offset, len, f) \
+ if (use_pcre16) \
+ PCHARS16(lv, p, offset, len, f); \
+ else \
+ PCHARS8(lv, p, offset, len, f)
+
+#define PCHARSV(p, offset, len, f) \
+ if (use_pcre16) \
+ PCHARSV16(p, offset, len, f); \
+ else \
+ PCHARSV8(p, offset, len, f)
+
+#define READ_CAPTURE_NAME(p, cn8, cn16, re) \
+ if (use_pcre16) \
+ READ_CAPTURE_NAME16(p, cn8, cn16, re); \
+ else \
+ READ_CAPTURE_NAME8(p, cn8, cn16, re)
+
+#define SET_PCRE_CALLOUT(callout) \
+ if (use_pcre16) \
+ SET_PCRE_CALLOUT16(callout); \
+ else \
+ SET_PCRE_CALLOUT8(callout)
+
+#define STRLEN(p) (use_pcre16? STRLEN16(p) : STRLEN8(p))
+
+#define PCRE_ASSIGN_JIT_STACK(extra, callback, userdata) \
+ if (use_pcre16) \
+ PCRE_ASSIGN_JIT_STACK16(extra, callback, userdata); \
+ else \
+ PCRE_ASSIGN_JIT_STACK8(extra, callback, userdata)
+
+#define PCRE_COMPILE(re, pat, options, error, erroffset, tables) \
+ if (use_pcre16) \
+ PCRE_COMPILE16(re, pat, options, error, erroffset, tables); \
+ else \
+ PCRE_COMPILE8(re, pat, options, error, erroffset, tables)
+
+#define PCRE_CONFIG pcre_config
+
+#define PCRE_COPY_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \
+ namesptr, cbuffer, size) \
+ if (use_pcre16) \
+ PCRE_COPY_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
+ namesptr, cbuffer, size); \
+ else \
+ PCRE_COPY_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
+ namesptr, cbuffer, size)
+
+#define PCRE_COPY_SUBSTRING(rc, bptr, offsets, count, i, cbuffer, size) \
+ if (use_pcre16) \
+ PCRE_COPY_SUBSTRING16(rc, bptr, offsets, count, i, cbuffer, size); \
+ else \
+ PCRE_COPY_SUBSTRING8(rc, bptr, offsets, count, i, cbuffer, size)
+
+#define PCRE_DFA_EXEC(count, re, extra, bptr, len, start_offset, options, \
+ offsets, size_offsets, workspace, size_workspace) \
+ if (use_pcre16) \
+ PCRE_DFA_EXEC16(count, re, extra, bptr, len, start_offset, options, \
+ offsets, size_offsets, workspace, size_workspace); \
+ else \
+ PCRE_DFA_EXEC8(count, re, extra, bptr, len, start_offset, options, \
+ offsets, size_offsets, workspace, size_workspace)
+
+#define PCRE_EXEC(count, re, extra, bptr, len, start_offset, options, \
+ offsets, size_offsets) \
+ if (use_pcre16) \
+ PCRE_EXEC16(count, re, extra, bptr, len, start_offset, options, \
+ offsets, size_offsets); \
+ else \
+ PCRE_EXEC8(count, re, extra, bptr, len, start_offset, options, \
+ offsets, size_offsets)
+
+#define PCRE_FREE_STUDY(extra) \
+ if (use_pcre16) \
+ PCRE_FREE_STUDY16(extra); \
+ else \
+ PCRE_FREE_STUDY8(extra)
+
+#define PCRE_FREE_SUBSTRING(substring) \
+ if (use_pcre16) \
+ PCRE_FREE_SUBSTRING16(substring); \
+ else \
+ PCRE_FREE_SUBSTRING8(substring)
+
+#define PCRE_FREE_SUBSTRING_LIST(listptr) \
+ if (use_pcre16) \
+ PCRE_FREE_SUBSTRING_LIST16(listptr); \
+ else \
+ PCRE_FREE_SUBSTRING_LIST8(listptr)
+
+#define PCRE_GET_NAMED_SUBSTRING(rc, re, bptr, offsets, count, \
+ getnamesptr, subsptr) \
+ if (use_pcre16) \
+ PCRE_GET_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
+ getnamesptr, subsptr); \
+ else \
+ PCRE_GET_NAMED_SUBSTRING8(rc, re, bptr, offsets, count, \
+ getnamesptr, subsptr)
+
+#define PCRE_GET_STRINGNUMBER(n, rc, ptr) \
+ if (use_pcre16) \
+ PCRE_GET_STRINGNUMBER16(n, rc, ptr); \
+ else \
+ PCRE_GET_STRINGNUMBER8(n, rc, ptr)
+
+#define PCRE_GET_SUBSTRING(rc, bptr, use_offsets, count, i, subsptr) \
+ if (use_pcre16) \
+ PCRE_GET_SUBSTRING16(rc, bptr, use_offsets, count, i, subsptr); \
+ else \
+ PCRE_GET_SUBSTRING8(rc, bptr, use_offsets, count, i, subsptr)
+
+#define PCRE_GET_SUBSTRING_LIST(rc, bptr, offsets, count, listptr) \
+ if (use_pcre16) \
+ PCRE_GET_SUBSTRING_LIST16(rc, bptr, offsets, count, listptr); \
+ else \
+ PCRE_GET_SUBSTRING_LIST8(rc, bptr, offsets, count, listptr)
+
+#define PCRE_JIT_STACK_ALLOC(startsize, maxsize) \
+ (use_pcre16 ? \
+ PCRE_JIT_STACK_ALLOC16(startsize, maxsize) \
+ :PCRE_JIT_STACK_ALLOC8(startsize, maxsize))
+
+#define PCRE_JIT_STACK_FREE(stack) \
+ if (use_pcre16) \
+ PCRE_JIT_STACK_FREE16(stack); \
+ else \
+ PCRE_JIT_STACK_FREE8(stack)
+
+#define PCRE_MAKETABLES \
+ (use_pcre16? pcre16_maketables() : pcre_maketables())
+
+#define PCRE_PATTERN_TO_HOST_BYTE_ORDER(rc, re, extra, tables) \
+ if (use_pcre16) \
+ PCRE_PATTERN_TO_HOST_BYTE_ORDER16(rc, re, extra, tables); \
+ else \
+ PCRE_PATTERN_TO_HOST_BYTE_ORDER8(rc, re, extra, tables)
+
+#define PCRE_PRINTINT(re, outfile, debug_lengths) \
+ if (use_pcre16) \
+ PCRE_PRINTINT16(re, outfile, debug_lengths); \
+ else \
+ PCRE_PRINTINT8(re, outfile, debug_lengths)
+
+#define PCRE_STUDY(extra, re, options, error) \
+ if (use_pcre16) \
+ PCRE_STUDY16(extra, re, options, error); \
+ else \
+ PCRE_STUDY8(extra, re, options, error)
+
+/* ----- Only 8-bit mode is supported ----- */
+
+#elif defined SUPPORT_PCRE8
+#define CHAR_SIZE 1
+#define PCHARS PCHARS8
+#define PCHARSV PCHARSV8
+#define READ_CAPTURE_NAME READ_CAPTURE_NAME8
+#define SET_PCRE_CALLOUT SET_PCRE_CALLOUT8
+#define STRLEN STRLEN8
+#define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK8
+#define PCRE_COMPILE PCRE_COMPILE8
+#define PCRE_CONFIG pcre_config
+#define PCRE_COPY_NAMED_SUBSTRING PCRE_COPY_NAMED_SUBSTRING8
+#define PCRE_COPY_SUBSTRING PCRE_COPY_SUBSTRING8
+#define PCRE_DFA_EXEC PCRE_DFA_EXEC8
+#define PCRE_EXEC PCRE_EXEC8
+#define PCRE_FREE_STUDY PCRE_FREE_STUDY8
+#define PCRE_FREE_SUBSTRING PCRE_FREE_SUBSTRING8
+#define PCRE_FREE_SUBSTRING_LIST PCRE_FREE_SUBSTRING_LIST8
+#define PCRE_GET_NAMED_SUBSTRING PCRE_GET_NAMED_SUBSTRING8
+#define PCRE_GET_STRINGNUMBER PCRE_GET_STRINGNUMBER8
+#define PCRE_GET_SUBSTRING PCRE_GET_SUBSTRING8
+#define PCRE_GET_SUBSTRING_LIST PCRE_GET_SUBSTRING_LIST8
+#define PCRE_JIT_STACK_ALLOC PCRE_JIT_STACK_ALLOC8
+#define PCRE_JIT_STACK_FREE PCRE_JIT_STACK_FREE8
+#define PCRE_MAKETABLES pcre_maketables()
+#define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER8
+#define PCRE_PRINTINT PCRE_PRINTINT8
+#define PCRE_STUDY PCRE_STUDY8
+
+/* ----- Only 16-bit mode is supported ----- */
+
+#else
+#define CHAR_SIZE 2
+#define PCHARS PCHARS16
+#define PCHARSV PCHARSV16
+#define READ_CAPTURE_NAME READ_CAPTURE_NAME16
+#define SET_PCRE_CALLOUT SET_PCRE_CALLOUT16
+#define STRLEN STRLEN16
+#define PCRE_ASSIGN_JIT_STACK PCRE_ASSIGN_JIT_STACK16
+#define PCRE_COMPILE PCRE_COMPILE16
+#define PCRE_CONFIG pcre16_config
+#define PCRE_COPY_NAMED_SUBSTRING PCRE_COPY_NAMED_SUBSTRING16
+#define PCRE_COPY_SUBSTRING PCRE_COPY_SUBSTRING16
+#define PCRE_DFA_EXEC PCRE_DFA_EXEC16
+#define PCRE_EXEC PCRE_EXEC16
+#define PCRE_FREE_STUDY PCRE_FREE_STUDY16
+#define PCRE_FREE_SUBSTRING PCRE_FREE_SUBSTRING16
+#define PCRE_FREE_SUBSTRING_LIST PCRE_FREE_SUBSTRING_LIST16
+#define PCRE_GET_NAMED_SUBSTRING PCRE_GET_NAMED_SUBSTRING16
+#define PCRE_GET_STRINGNUMBER PCRE_GET_STRINGNUMBER16
+#define PCRE_GET_SUBSTRING PCRE_GET_SUBSTRING16
+#define PCRE_GET_SUBSTRING_LIST PCRE_GET_SUBSTRING_LIST16
+#define PCRE_JIT_STACK_ALLOC PCRE_JIT_STACK_ALLOC16
+#define PCRE_JIT_STACK_FREE PCRE_JIT_STACK_FREE16
+#define PCRE_MAKETABLES pcre16_maketables()
+#define PCRE_PATTERN_TO_HOST_BYTE_ORDER PCRE_PATTERN_TO_HOST_BYTE_ORDER16
+#define PCRE_PRINTINT PCRE_PRINTINT16
+#define PCRE_STUDY PCRE_STUDY16
+#endif
+
+/* ----- End of mode-specific function call macros ----- */
+
/* Other parameters */
@@ -171,6 +610,10 @@
#endif
#endif
+#if !defined NODFA
+#define DFA_WS_DIMENSION 1000
+#endif
+
/* This is the default loop count for timing. */
#define LOOPREPEAT 500000
@@ -185,17 +628,117 @@
static int callout_fail_id;
static int debug_lengths;
static int first_callout;
+static int jit_was_used;
static int locale_set = 0;
static int show_malloc;
-static int use_utf8;
+static int use_utf;
static size_t gotten_store;
+static size_t first_gotten_store = 0;
+static const unsigned char *last_callout_mark = NULL;
/* The buffers grow automatically if very long input lines are encountered. */
static int buffer_size = 50000;
-static uschar *buffer = NULL;
-static uschar *dbuffer = NULL;
-static uschar *pbuffer = NULL;
+static pcre_uint8 *buffer = NULL;
+static pcre_uint8 *dbuffer = NULL;
+static pcre_uint8 *pbuffer = NULL;
+
+/* Another buffer is needed translation to 16-bit character strings. It will
+obtained and extended as required. */
+
+#ifdef SUPPORT_PCRE16
+static int buffer16_size = 0;
+static pcre_uint16 *buffer16 = NULL;
+
+#ifdef SUPPORT_PCRE8
+
+/* We need the table of operator lengths that is used for 16-bit compiling, in
+order to swap bytes in a pattern for saving/reloading testing. Luckily, the
+data is defined as a macro. However, we must ensure that LINK_SIZE is adjusted
+appropriately for the 16-bit world. Just as a safety check, make sure that
+COMPILE_PCRE16 is *not* set. */
+
+#ifdef COMPILE_PCRE16
+#error COMPILE_PCRE16 must not be set when compiling pcretest.c
+#endif
+
+#if LINK_SIZE == 2
+#undef LINK_SIZE
+#define LINK_SIZE 1
+#elif LINK_SIZE == 3 || LINK_SIZE == 4
+#undef LINK_SIZE
+#define LINK_SIZE 2
+#else
+#error LINK_SIZE must be either 2, 3, or 4
+#endif
+
+#undef IMM2_SIZE
+#define IMM2_SIZE 1
+
+#endif /* SUPPORT_PCRE8 */
+
+static const pcre_uint16 OP_lengths16[] = { OP_LENGTHS };
+#endif /* SUPPORT_PCRE16 */
+
+/* If we have 8-bit support, default use_pcre16 to false; if there is also
+16-bit support, it can be changed by an option. If there is no 8-bit support,
+there must be 16-bit support, so default it to 1. */
+
+#ifdef SUPPORT_PCRE8
+static int use_pcre16 = 0;
+#else
+static int use_pcre16 = 1;
+#endif
+
+/* JIT study options for -s+n and /S+n where '1' <= n <= '7'. */
+
+static int jit_study_bits[] =
+ {
+ PCRE_STUDY_JIT_COMPILE,
+ PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE,
+ PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE,
+ PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE,
+ PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE,
+ PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE,
+ PCRE_STUDY_JIT_COMPILE + PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE +
+ PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
+};
+
+/* Textual explanations for runtime error codes */
+
+static const char *errtexts[] = {
+ NULL, /* 0 is no error */
+ NULL, /* NOMATCH is handled specially */
+ "NULL argument passed",
+ "bad option value",
+ "magic number missing",
+ "unknown opcode - pattern overwritten?",
+ "no more memory",
+ NULL, /* never returned by pcre_exec() or pcre_dfa_exec() */
+ "match limit exceeded",
+ "callout error code",
+ NULL, /* BADUTF8/16 is handled specially */
+ NULL, /* BADUTF8/16 offset is handled specially */
+ NULL, /* PARTIAL is handled specially */
+ "not used - internal error",
+ "internal error - pattern overwritten?",
+ "bad count value",
+ "item unsupported for DFA matching",
+ "backreference condition or recursion test not supported for DFA matching",
+ "match limit not supported for DFA matching",
+ "workspace size exceeded in DFA matching",
+ "too much recursion for DFA matching",
+ "recursion limit exceeded",
+ "not used - internal error",
+ "invalid combination of newline options",
+ "bad offset value",
+ NULL, /* SHORTUTF8/16 is handled specially */
+ "nested recursion at the same subject position",
+ "JIT stack limit reached",
+ "pattern compiled in wrong mode: 8-bit/16-bit error",
+ "pattern compiled with other endianness",
+ "invalid data in workspace for DFA restart"
+};
/*************************************************
@@ -210,7 +753,7 @@
/* This is the set of tables distributed as default with PCRE. It recognizes
only ASCII characters. */
-static const unsigned char tables0[] = {
+static const pcre_uint8 tables0[] = {
/* This table is a lower casing table. */
@@ -383,7 +926,7 @@
be at least an approximation of ISO 8859. In particular, there are characters
greater than 128 that are marked as spaces, letters, etc. */
-static const unsigned char tables1[] = {
+static const pcre_uint8 tables1[] = {
0,1,2,3,4,5,6,7,
8,9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,
@@ -546,6 +1089,188 @@
#endif /* HAVE_STRERROR */
+/*************************************************
+* JIT memory callback *
+*************************************************/
+
+static pcre_jit_stack* jit_callback(void *arg)
+{
+jit_was_used = TRUE;
+return (pcre_jit_stack *)arg;
+}
+
+
+#if !defined NOUTF || defined SUPPORT_PCRE16
+/*************************************************
+* Convert UTF-8 string to value *
+*************************************************/
+
+/* This function takes one or more bytes that represents a UTF-8 character,
+and returns the value of the character.
+
+Argument:
+ utf8bytes a pointer to the byte vector
+ vptr a pointer to an int to receive the value
+
+Returns: > 0 => the number of bytes consumed
+ -6 to 0 => malformed UTF-8 character at offset = (-return)
+*/
+
+static int
+utf82ord(pcre_uint8 *utf8bytes, int *vptr)
+{
+int c = *utf8bytes++;
+int d = c;
+int i, j, s;
+
+for (i = -1; i < 6; i++) /* i is number of additional bytes */
+ {
+ if ((d & 0x80) == 0) break;
+ d <<= 1;
+ }
+
+if (i == -1) { *vptr = c; return 1; } /* ascii character */
+if (i == 0 || i == 6) return 0; /* invalid UTF-8 */
+
+/* i now has a value in the range 1-5 */
+
+s = 6*i;
+d = (c & utf8_table3[i]) << s;
+
+for (j = 0; j < i; j++)
+ {
+ c = *utf8bytes++;
+ if ((c & 0xc0) != 0x80) return -(j+1);
+ s -= 6;
+ d |= (c & 0x3f) << s;
+ }
+
+/* Check that encoding was the correct unique one */
+
+for (j = 0; j < utf8_table1_size; j++)
+ if (d <= utf8_table1[j]) break;
+if (j != i) return -(i+1);
+
+/* Valid value */
+
+*vptr = d;
+return i+1;
+}
+#endif /* NOUTF || SUPPORT_PCRE16 */
+
+
+
+#if !defined NOUTF || defined SUPPORT_PCRE16
+/*************************************************
+* Convert character value to UTF-8 *
+*************************************************/
+
+/* This function takes an integer value in the range 0 - 0x7fffffff
+and encodes it as a UTF-8 character in 0 to 6 bytes.
+
+Arguments:
+ cvalue the character value
+ utf8bytes pointer to buffer for result - at least 6 bytes long
+
+Returns: number of characters placed in the buffer
+*/
+
+static int
+ord2utf8(int cvalue, pcre_uint8 *utf8bytes)
+{
+register int i, j;
+for (i = 0; i < utf8_table1_size; i++)
+ if (cvalue <= utf8_table1[i]) break;
+utf8bytes += i;
+for (j = i; j > 0; j--)
+ {
+ *utf8bytes-- = 0x80 | (cvalue & 0x3f);
+ cvalue >>= 6;
+ }
+*utf8bytes = utf8_table2[i] | cvalue;
+return i + 1;
+}
+#endif
+
+
+#ifdef SUPPORT_PCRE16
+/*************************************************
+* Convert a string to 16-bit *
+*************************************************/
+
+/* In non-UTF mode, the space needed for a 16-bit string is exactly double the
+8-bit size. For a UTF-8 string, the size needed for UTF-16 is no more than
+double, because up to 0xffff uses no more than 3 bytes in UTF-8 but possibly 4
+in UTF-16. Higher values use 4 bytes in UTF-8 and up to 4 bytes in UTF-16. The
+result is always left in buffer16.
+
+Note that this function does not object to surrogate values. This is
+deliberate; it makes it possible to construct UTF-16 strings that are invalid,
+for the purpose of testing that they are correctly faulted.
+
+Patterns to be converted are either plain ASCII or UTF-8; data lines are always
+in UTF-8 so that values greater than 255 can be handled.
+
+Arguments:
+ data TRUE if converting a data line; FALSE for a regex
+ p points to a byte string
+ utf true if UTF-8 (to be converted to UTF-16)
+ len number of bytes in the string (excluding trailing zero)
+
+Returns: number of 16-bit data items used (excluding trailing zero)
+ OR -1 if a UTF-8 string is malformed
+ OR -2 if a value > 0x10ffff is encountered
+ OR -3 if a value > 0xffff is encountered when not in UTF mode
+*/
+
+static int
+to16(int data, pcre_uint8 *p, int utf, int len)
+{
+pcre_uint16 *pp;
+
+if (buffer16_size < 2*len + 2)
+ {
+ if (buffer16 != NULL) free(buffer16);
+ buffer16_size = 2*len + 2;
+ buffer16 = (pcre_uint16 *)malloc(buffer16_size);
+ if (buffer16 == NULL)
+ {
+ fprintf(stderr, "pcretest: malloc(%d) failed for buffer16\n", buffer16_size);
+ exit(1);
+ }
+ }
+
+pp = buffer16;
+
+if (!utf && !data)
+ {
+ while (len-- > 0) *pp++ = *p++;
+ }
+
+else
+ {
+ int c = 0;
+ while (len > 0)
+ {
+ int chlen = utf82ord(p, &c);
+ if (chlen <= 0) return -1;
+ if (c > 0x10ffff) return -2;
+ p += chlen;
+ len -= chlen;
+ if (c < 0x10000) *pp++ = c; else
+ {
+ if (!utf) return -3;
+ c -= 0x10000;
+ *pp++ = 0xD800 | (c >> 10);
+ *pp++ = 0xDC00 | (c & 0x3ff);
+ }
+ }
+ }
+
+*pp = 0;
+return pp - buffer16;
+}
+#endif
/*************************************************
@@ -571,24 +1296,24 @@
NULL if no data read and EOF reached
*/
-static uschar *
-extend_inputline(FILE *f, uschar *start, const char *prompt)
+static pcre_uint8 *
+extend_inputline(FILE *f, pcre_uint8 *start, const char *prompt)
{
-uschar *here = start;
+pcre_uint8 *here = start;
for (;;)
{
- int rlen = (int)(buffer_size - (here - buffer));
+ size_t rlen = (size_t)(buffer_size - (here - buffer));
if (rlen > 1000)
{
int dlen;
- /* If libreadline support is required, use readline() to read a line if the
- input is a terminal. Note that readline() removes the trailing newline, so
- we must put it back again, to be compatible with fgets(). */
+ /* If libreadline or libedit support is required, use readline() to read a
+ line if the input is a terminal. Note that readline() removes the trailing
+ newline, so we must put it back again, to be compatible with fgets(). */
-#ifdef SUPPORT_LIBREADLINE
+#if defined(SUPPORT_LIBREADLINE) || defined(SUPPORT_LIBEDIT)
if (isatty(fileno(f)))
{
size_t len;
@@ -621,9 +1346,9 @@
else
{
int new_buffer_size = 2*buffer_size;
- uschar *new_buffer = (unsigned char *)malloc(new_buffer_size);
- uschar *new_dbuffer = (unsigned char *)malloc(new_buffer_size);
- uschar *new_pbuffer = (unsigned char *)malloc(new_buffer_size);
+ pcre_uint8 *new_buffer = (pcre_uint8 *)malloc(new_buffer_size);
+ pcre_uint8 *new_dbuffer = (pcre_uint8 *)malloc(new_buffer_size);
+ pcre_uint8 *new_pbuffer = (pcre_uint8 *)malloc(new_buffer_size);
if (new_buffer == NULL || new_dbuffer == NULL || new_pbuffer == NULL)
{
@@ -654,10 +1379,6 @@
-
-
-
-
/*************************************************
* Read number from string *
*************************************************/
@@ -674,7 +1395,7 @@
*/
static int
-get_value(unsigned char *str, unsigned char **endptr)
+get_value(pcre_uint8 *str, pcre_uint8 **endptr)
{
int result = 0;
while(*str != 0 && isspace(*str)) str++;
@@ -685,165 +1406,187 @@
-
/*************************************************
-* Convert UTF-8 string to value *
+* Print one character *
*************************************************/
-/* This function takes one or more bytes that represents a UTF-8 character,
-and returns the value of the character.
-
-Argument:
- utf8bytes a pointer to the byte vector
- vptr a pointer to an int to receive the value
-
-Returns: > 0 => the number of bytes consumed
- -6 to 0 => malformed UTF-8 character at offset = (-return)
-*/
-
-#if !defined NOUTF8
+/* Print a single character either literally, or as a hex escape. */
-static int
-utf82ord(unsigned char *utf8bytes, int *vptr)
+static int pchar(int c, FILE *f)
{
-int c = *utf8bytes++;
-int d = c;
-int i, j, s;
+if (PRINTOK(c))
+ {
+ if (f != NULL) fprintf(f, "%c", c);
+ return 1;
+ }
-for (i = -1; i < 6; i++) /* i is number of additional bytes */
+if (c < 0x100)
{
- if ((d & 0x80) == 0) break;
- d <<= 1;
+ if (use_utf)
+ {
+ if (f != NULL) fprintf(f, "\\x{%02x}", c);
+ return 6;
+ }
+ else
+ {
+ if (f != NULL) fprintf(f, "\\x%02x", c);
+ return 4;
+ }
}
-if (i == -1) { *vptr = c; return 1; } /* ascii character */
-if (i == 0 || i == 6) return 0; /* invalid UTF-8 */
+if (f != NULL) fprintf(f, "\\x{%02x}", c);
+return (c <= 0x000000ff)? 6 :
+ (c <= 0x00000fff)? 7 :
+ (c <= 0x0000ffff)? 8 :
+ (c <= 0x000fffff)? 9 : 10;
+}
-/* i now has a value in the range 1-5 */
-s = 6*i;
-d = (c & utf8_table3[i]) << s;
-for (j = 0; j < i; j++)
- {
- c = *utf8bytes++;
- if ((c & 0xc0) != 0x80) return -(j+1);
- s -= 6;
- d |= (c & 0x3f) << s;
- }
+#ifdef SUPPORT_PCRE8
+/*************************************************
+* Print 8-bit character string *
+*************************************************/
-/* Check that encoding was the correct unique one */
+/* Must handle UTF-8 strings in utf8 mode. Yields number of characters printed.
+If handed a NULL file, just counts chars without printing. */
-for (j = 0; j < utf8_table1_size; j++)
- if (d <= utf8_table1[j]) break;
-if (j != i) return -(i+1);
+static int pchars(pcre_uint8 *p, int length, FILE *f)
+{
+int c = 0;
+int yield = 0;
-/* Valid value */
+if (length < 0)
+ length = strlen((char *)p);
-*vptr = d;
-return i+1;
-}
+while (length-- > 0)
+ {
+#if !defined NOUTF
+ if (use_utf)
+ {
+ int rc = utf82ord(p, &c);
+ if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */
+ {
+ length -= rc - 1;
+ p += rc;
+ yield += pchar(c, f);
+ continue;
+ }
+ }
+#endif
+ c = *p++;
+ yield += pchar(c, f);
+ }
+return yield;
+}
#endif
+#ifdef SUPPORT_PCRE16
/*************************************************
-* Convert character value to UTF-8 *
+* Find length of 0-terminated 16-bit string *
*************************************************/
-/* This function takes an integer value in the range 0 - 0x7fffffff
-and encodes it as a UTF-8 character in 0 to 6 bytes.
-
-Arguments:
- cvalue the character value
- utf8bytes pointer to buffer for result - at least 6 bytes long
-
-Returns: number of characters placed in the buffer
-*/
-
-#if !defined NOUTF8
-
-static int
-ord2utf8(int cvalue, uschar *utf8bytes)
+static int strlen16(PCRE_SPTR16 p)
{
-register int i, j;
-for (i = 0; i < utf8_table1_size; i++)
- if (cvalue <= utf8_table1[i]) break;
-utf8bytes += i;
-for (j = i; j > 0; j--)
- {
- *utf8bytes-- = 0x80 | (cvalue & 0x3f);
- cvalue >>= 6;
- }
-*utf8bytes = utf8_table2[i] | cvalue;
-return i + 1;
+int len = 0;
+while (*p++ != 0) len++;
+return len;
}
-
-#endif
-
+#endif /* SUPPORT_PCRE16 */
+#ifdef SUPPORT_PCRE16
/*************************************************
-* Print character string *
+* Print 16-bit character string *
*************************************************/
-/* Character string printing function. Must handle UTF-8 strings in utf8
-mode. Yields number of characters printed. If handed a NULL file, just counts
-chars without printing. */
+/* Must handle UTF-16 strings in utf mode. Yields number of characters printed.
+If handed a NULL file, just counts chars without printing. */
-static int pchars(unsigned char *p, int length, FILE *f)
+static int pchars16(PCRE_SPTR16 p, int length, FILE *f)
{
-int c = 0;
int yield = 0;
+if (length < 0)
+ length = strlen16(p);
+
while (length-- > 0)
{
-#if !defined NOUTF8
- if (use_utf8)
+ int c = *p++ & 0xffff;
+#if !defined NOUTF
+ if (use_utf && c >= 0xD800 && c < 0xDC00 && length > 0)
{
- int rc = utf82ord(p, &c);
-
- if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */
+ int d = *p & 0xffff;
+ if (d >= 0xDC00 && d < 0xDFFF)
{
- length -= rc - 1;
- p += rc;
- if (PRINTHEX(c))
- {
- if (f != NULL) fprintf(f, "%c", c);
- yield++;
- }
- else
- {
- int n = 4;
- if (f != NULL) fprintf(f, "\\x{%02x}", c);
- yield += (n <= 0x000000ff)? 2 :
- (n <= 0x00000fff)? 3 :
- (n <= 0x0000ffff)? 4 :
- (n <= 0x000fffff)? 5 : 6;
- }
- continue;
+ c = ((c & 0x3ff) << 10) + (d & 0x3ff) + 0x10000;
+ length--;
+ p++;
}
}
#endif
+ yield += pchar(c, f);
+ }
- /* Not UTF-8, or malformed UTF-8 */
+return yield;
+}
+#endif /* SUPPORT_PCRE16 */
- c = *p++;
- if (PRINTHEX(c))
- {
- if (f != NULL) fprintf(f, "%c", c);
- yield++;
- }
- else
- {
- if (f != NULL) fprintf(f, "\\x%02x", c);
- yield += 4;
- }
+
+
+#ifdef SUPPORT_PCRE8
+/*************************************************
+* Read a capture name (8-bit) and check it *
+*************************************************/
+
+static pcre_uint8 *
+read_capture_name8(pcre_uint8 *p, pcre_uint8 **pp, pcre *re)
+{
+pcre_uint8 *npp = *pp;
+while (isalnum(*p)) *npp++ = *p++;
+*npp++ = 0;
+*npp = 0;
+if (pcre_get_stringnumber(re, (char *)(*pp)) < 0)
+ {
+ fprintf(outfile, "no parentheses with name \"");
+ PCHARSV(*pp, 0, -1, outfile);
+ fprintf(outfile, "\"\n");
}
-return yield;
+*pp = npp;
+return p;
}
+#endif /* SUPPORT_PCRE8 */
+
+
+
+#ifdef SUPPORT_PCRE16
+/*************************************************
+* Read a capture name (16-bit) and check it *
+*************************************************/
+
+/* Note that the text being read is 8-bit. */
+
+static pcre_uint8 *
+read_capture_name16(pcre_uint8 *p, pcre_uint16 **pp, pcre *re)
+{
+pcre_uint16 *npp = *pp;
+while (isalnum(*p)) *npp++ = *p++;
+*npp++ = 0;
+*npp = 0;
+if (pcre16_get_stringnumber((pcre16 *)re, (PCRE_SPTR16)(*pp)) < 0)
+ {
+ fprintf(outfile, "no parentheses with name \"");
+ PCHARSV(*pp, 0, -1, outfile);
+ fprintf(outfile, "\"\n");
+ }
+*pp = npp;
+return p;
+}
+#endif /* SUPPORT_PCRE16 */
@@ -872,7 +1615,7 @@
else
{
fprintf(f, "%2d: ", i/2);
- (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i],
+ PCHARSV(cb->subject, cb->offset_vector[i],
cb->offset_vector[i+1] - cb->offset_vector[i], f);
fprintf(f, "\n");
}
@@ -885,13 +1628,13 @@
if (f != NULL) fprintf(f, "--->");
-pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f);
-post_start = pchars((unsigned char *)(cb->subject + cb->start_match),
+PCHARS(pre_start, cb->subject, 0, cb->start_match, f);
+PCHARS(post_start, cb->subject, cb->start_match,
cb->current_position - cb->start_match, f);
-subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL);
+PCHARS(subject_length, cb->subject, 0, cb->subject_length, NULL);
-(void)pchars((unsigned char *)(cb->subject + cb->current_position),
+PCHARSV(cb->subject, cb->current_position,
cb->subject_length - cb->current_position, f);
if (f != NULL) fprintf(f, "\n");
@@ -928,6 +1671,19 @@
fprintf(outfile, "\n");
first_callout = 0;
+if (cb->mark != last_callout_mark)
+ {
+ if (cb->mark == NULL)
+ fprintf(outfile, "Latest Mark: \n");
+ else
+ {
+ fprintf(outfile, "Latest Mark: ");
+ PCHARSV(cb->mark, 0, -1, outfile);
+ putc('\n', outfile);
+ }
+ last_callout_mark = cb->mark;
+ }
+
if (cb->callout_data != NULL)
{
int callout_data = *((int *)(cb->callout_data));
@@ -947,13 +1703,15 @@
* Local malloc functions *
*************************************************/
-/* Alternative malloc function, to test functionality and show the size of the
-compiled re. */
+/* Alternative malloc function, to test functionality and save the size of a
+compiled re, which is the first store request that pcre_compile() makes. The
+show_malloc variable is set only during matching. */
static void *new_malloc(size_t size)
{
void *block = malloc(size);
gotten_store = size;
+if (first_gotten_store == 0) first_gotten_store = size;
if (show_malloc)
fprintf(outfile, "malloc %3d %p\n", (int)size, block);
return block;
@@ -966,7 +1724,6 @@
free(block);
}
-
/* For recursion malloc/free, to test stacking calls */
static void *stack_malloc(size_t size)
@@ -989,31 +1746,270 @@
* Call pcre_fullinfo() *
*************************************************/
-/* Get one piece of information from the pcre_fullinfo() function */
+/* Get one piece of information from the pcre_fullinfo() function. When only
+one of 8-bit or 16-bit is supported, use_pcre16 should always have the correct
+value, but the code is defensive.
+
+Arguments:
+ re compiled regex
+ study study data
+ option PCRE_INFO_xxx option
+ ptr where to put the data
+
+Returns: 0 when OK, < 0 on error
+*/
-static void new_info(pcre *re, pcre_extra *study, int option, void *ptr)
+static int
+new_info(pcre *re, pcre_extra *study, int option, void *ptr)
{
int rc;
-if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0)
- fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option);
+
+if (use_pcre16)
+#ifdef SUPPORT_PCRE16
+ rc = pcre16_fullinfo((pcre16 *)re, (pcre16_extra *)study, option, ptr);
+#else
+ rc = PCRE_ERROR_BADMODE;
+#endif
+else
+#ifdef SUPPORT_PCRE8
+ rc = pcre_fullinfo(re, study, option, ptr);
+#else
+ rc = PCRE_ERROR_BADMODE;
+#endif
+
+if (rc < 0)
+ {
+ fprintf(outfile, "Error %d from pcre%s_fullinfo(%d)\n", rc,
+ use_pcre16? "16" : "", option);
+ if (rc == PCRE_ERROR_BADMODE)
+ fprintf(outfile, "Running in %s-bit mode but pattern was compiled in "
+ "%s-bit mode\n", use_pcre16? "16":"8", use_pcre16? "8":"16");
+ }
+
+return rc;
}
/*************************************************
-* Byte flipping function *
+* Swap byte functions *
*************************************************/
-static unsigned long int
-byteflip(unsigned long int value, int n)
+/* The following functions swap the bytes of a pcre_uint16 and pcre_uint32
+value, respectively.
+
+Arguments:
+ value any number
+
+Returns: the byte swapped value
+*/
+
+static pcre_uint32
+swap_uint32(pcre_uint32 value)
{
-if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
return ((value & 0x000000ff) << 24) |
((value & 0x0000ff00) << 8) |
((value & 0x00ff0000) >> 8) |
- ((value & 0xff000000) >> 24);
+ (value >> 24);
}
+static pcre_uint16
+swap_uint16(pcre_uint16 value)
+{
+return (value >> 8) | (value << 8);
+}
+
+
+
+/*************************************************
+* Flip bytes in a compiled pattern *
+*************************************************/
+
+/* This function is called if the 'F' option was present on a pattern that is
+to be written to a file. We flip the bytes of all the integer fields in the
+regex data block and the study block. In 16-bit mode this also flips relevant
+bytes in the pattern itself. This is to make it possible to test PCRE's
+ability to reload byte-flipped patterns, e.g. those compiled on a different
+architecture. */
+
+static void
+regexflip(pcre *ere, pcre_extra *extra)
+{
+REAL_PCRE *re = (REAL_PCRE *)ere;
+#ifdef SUPPORT_PCRE16
+int op;
+pcre_uint16 *ptr = (pcre_uint16 *)re + re->name_table_offset;
+int length = re->name_count * re->name_entry_size;
+#ifdef SUPPORT_UTF
+BOOL utf = (re->options & PCRE_UTF16) != 0;
+BOOL utf16_char = FALSE;
+#endif /* SUPPORT_UTF */
+#endif /* SUPPORT_PCRE16 */
+
+/* Always flip the bytes in the main data block and study blocks. */
+
+re->magic_number = REVERSED_MAGIC_NUMBER;
+re->size = swap_uint32(re->size);
+re->options = swap_uint32(re->options);
+re->flags = swap_uint16(re->flags);
+re->top_bracket = swap_uint16(re->top_bracket);
+re->top_backref = swap_uint16(re->top_backref);
+re->first_char = swap_uint16(re->first_char);
+re->req_char = swap_uint16(re->req_char);
+re->name_table_offset = swap_uint16(re->name_table_offset);
+re->name_entry_size = swap_uint16(re->name_entry_size);
+re->name_count = swap_uint16(re->name_count);
+
+if (extra != NULL)
+ {
+ pcre_study_data *rsd = (pcre_study_data *)(extra->study_data);
+ rsd->size = swap_uint32(rsd->size);
+ rsd->flags = swap_uint32(rsd->flags);
+ rsd->minlength = swap_uint32(rsd->minlength);
+ }
+
+/* In 8-bit mode, that is all we need to do. In 16-bit mode we must swap bytes
+in the name table, if present, and then in the pattern itself. */
+
+#ifdef SUPPORT_PCRE16
+if (!use_pcre16) return;
+
+while(TRUE)
+ {
+ /* Swap previous characters. */
+ while (length-- > 0)
+ {
+ *ptr = swap_uint16(*ptr);
+ ptr++;
+ }
+#ifdef SUPPORT_UTF
+ if (utf16_char)
+ {
+ if ((ptr[-1] & 0xfc00) == 0xd800)
+ {
+ /* We know that there is only one extra character in UTF-16. */
+ *ptr = swap_uint16(*ptr);
+ ptr++;
+ }
+ }
+ utf16_char = FALSE;
+#endif /* SUPPORT_UTF */
+
+ /* Get next opcode. */
+
+ length = 0;
+ op = *ptr;
+ *ptr++ = swap_uint16(op);
+
+ switch (op)
+ {
+ case OP_END:
+ return;
+
+#ifdef SUPPORT_UTF
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ if (utf) utf16_char = TRUE;
+#endif
+ /* Fall through. */
+
+ default:
+ length = OP_lengths16[op] - 1;
+ break;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ /* Skip the character bit map. */
+ ptr += 32/sizeof(pcre_uint16);
+ length = 0;
+ break;
+
+ case OP_XCLASS:
+ /* LINK_SIZE can be 1 or 2 in 16 bit mode. */
+ if (LINK_SIZE > 1)
+ length = (int)((((unsigned int)(ptr[0]) << 16) | (unsigned int)(ptr[1]))
+ - (1 + LINK_SIZE + 1));
+ else
+ length = (int)((unsigned int)(ptr[0]) - (1 + LINK_SIZE + 1));
+
+ /* Reverse the size of the XCLASS instance. */
+ *ptr = swap_uint16(*ptr);
+ ptr++;
+ if (LINK_SIZE > 1)
+ {
+ *ptr = swap_uint16(*ptr);
+ ptr++;
+ }
+
+ op = *ptr;
+ *ptr = swap_uint16(op);
+ ptr++;
+ if ((op & XCL_MAP) != 0)
+ {
+ /* Skip the character bit map. */
+ ptr += 32/sizeof(pcre_uint16);
+ length -= 32/sizeof(pcre_uint16);
+ }
+ break;
+ }
+ }
+/* Control should never reach here in 16 bit mode. */
+#endif /* SUPPORT_PCRE16 */
+}
@@ -1022,7 +2018,7 @@
*************************************************/
static int
-check_match_limit(pcre *re, pcre_extra *extra, uschar *bptr, int len,
+check_match_limit(pcre *re, pcre_extra *extra, pcre_uint8 *bptr, int len,
int start_offset, int options, int *use_offsets, int use_size_offsets,
int flag, unsigned long int *limit, int errnumber, const char *msg)
{
@@ -1037,7 +2033,7 @@
{
*limit = mid;
- count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options,
+ PCRE_EXEC(count, re, extra, bptr, len, start_offset, options,
use_offsets, use_size_offsets);
if (count == errnumber)
@@ -1082,7 +2078,7 @@
*/
static int
-strncmpic(uschar *s, uschar *t, int n)
+strncmpic(pcre_uint8 *s, pcre_uint8 *t, int n)
{
while (n--)
{
@@ -1109,15 +2105,15 @@
*/
static int
-check_newline(uschar *p, FILE *f)
+check_newline(pcre_uint8 *p, FILE *f)
{
-if (strncmpic(p, (uschar *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;
-if (strncmpic(p, (uschar *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;
-if (strncmpic(p, (uschar *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
-if (strncmpic(p, (uschar *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;
-if (strncmpic(p, (uschar *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;
-if (strncmpic(p, (uschar *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF;
-if (strncmpic(p, (uschar *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE;
+if (strncmpic(p, (pcre_uint8 *)"cr>", 3) == 0) return PCRE_NEWLINE_CR;
+if (strncmpic(p, (pcre_uint8 *)"lf>", 3) == 0) return PCRE_NEWLINE_LF;
+if (strncmpic(p, (pcre_uint8 *)"crlf>", 5) == 0) return PCRE_NEWLINE_CRLF;
+if (strncmpic(p, (pcre_uint8 *)"anycrlf>", 8) == 0) return PCRE_NEWLINE_ANYCRLF;
+if (strncmpic(p, (pcre_uint8 *)"any>", 4) == 0) return PCRE_NEWLINE_ANY;
+if (strncmpic(p, (pcre_uint8 *)"bsr_anycrlf>", 12) == 0) return PCRE_BSR_ANYCRLF;
+if (strncmpic(p, (pcre_uint8 *)"bsr_unicode>", 12) == 0) return PCRE_BSR_UNICODE;
fprintf(f, "Unknown newline type at: <%s\n", p);
return 0;
}
@@ -1133,14 +2129,26 @@
{
printf("Usage: pcretest [options] [ [