summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2014-02-04 10:32:09 +0100
committerAnatol Belski <ab@php.net>2014-02-04 10:32:09 +0100
commit2e8e2db82aa0ee78c0707f0768dc6285b31b0a15 (patch)
tree7a104d276e689efe162039f6b5508d43899599d9
parent0e764dc657f2e802e41b10690edbad7a70d041d2 (diff)
parent353e2643ab61bd46f0bac6dc3b8c66b7662cc69f (diff)
downloadphp-git-2e8e2db82aa0ee78c0707f0768dc6285b31b0a15.tar.gz
Merge branch 'PHP-5.6'
* PHP-5.6: pcre upgraded to 8.34
-rw-r--r--ext/pcre/pcrelib/AUTHORS6
-rw-r--r--ext/pcre/pcrelib/ChangeLog378
-rw-r--r--ext/pcre/pcrelib/HACKING269
-rw-r--r--ext/pcre/pcrelib/LICENCE6
-rw-r--r--ext/pcre/pcrelib/NEWS71
-rw-r--r--ext/pcre/pcrelib/README113
-rw-r--r--ext/pcre/pcrelib/config.h4
-rw-r--r--ext/pcre/pcrelib/doc/pcre.txt4105
-rw-r--r--ext/pcre/pcrelib/pcre.h50
-rw-r--r--ext/pcre/pcrelib/pcre_chartables.c2
-rw-r--r--ext/pcre/pcrelib/pcre_compile.c3619
-rw-r--r--ext/pcre/pcrelib/pcre_config.c4
-rw-r--r--ext/pcre/pcrelib/pcre_exec.c959
-rw-r--r--ext/pcre/pcrelib/pcre_fullinfo.c16
-rw-r--r--ext/pcre/pcrelib/pcre_internal.h459
-rw-r--r--ext/pcre/pcrelib/pcre_maketables.c27
-rw-r--r--ext/pcre/pcrelib/pcre_study.c86
-rw-r--r--ext/pcre/pcrelib/pcre_tables.c15
-rw-r--r--ext/pcre/pcrelib/pcre_ucd.c753
-rw-r--r--ext/pcre/pcrelib/pcre_valid_utf8.c15
-rw-r--r--ext/pcre/pcrelib/pcre_xclass.c101
-rw-r--r--ext/pcre/pcrelib/pcreposix.c12
-rw-r--r--ext/pcre/pcrelib/testdata/grepbinarybin0 -> 45 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/grepfilelist3
-rw-r--r--ext/pcre/pcrelib/testdata/grepinput315
-rw-r--r--ext/pcre/pcrelib/testdata/grepinput84
-rw-r--r--ext/pcre/pcrelib/testdata/grepinputv4
-rw-r--r--ext/pcre/pcrelib/testdata/grepoutput38
-rw-r--r--ext/pcre/pcrelib/testdata/grepoutput84
-rw-r--r--ext/pcre/pcrelib/testdata/grepoutputN18
-rw-r--r--ext/pcre/pcrelib/testdata/greppatN42
-rw-r--r--ext/pcre/pcrelib/testdata/saved16bin0 -> 86 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/saved16BE-1bin0 -> 410 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/saved16BE-2bin0 -> 344 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/saved16LE-1bin0 -> 410 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/saved16LE-2bin0 -> 344 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/saved32bin0 -> 108 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/saved32BE-1bin0 -> 552 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/saved32BE-2bin0 -> 456 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/saved32LE-1bin0 -> 552 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/saved32LE-2bin0 -> 456 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/saved8bin0 -> 77 bytes
-rw-r--r--ext/pcre/pcrelib/testdata/testinput1467
-rw-r--r--ext/pcre/pcrelib/testdata/testinput10108
-rw-r--r--ext/pcre/pcrelib/testdata/testinput11135
-rw-r--r--ext/pcre/pcrelib/testdata/testinput1290
-rw-r--r--ext/pcre/pcrelib/testdata/testinput139
-rw-r--r--ext/pcre/pcrelib/testdata/testinput14343
-rw-r--r--ext/pcre/pcrelib/testdata/testinput15366
-rw-r--r--ext/pcre/pcrelib/testdata/testinput1635
-rw-r--r--ext/pcre/pcrelib/testdata/testinput17307
-rw-r--r--ext/pcre/pcrelib/testdata/testinput18300
-rw-r--r--ext/pcre/pcrelib/testdata/testinput1922
-rw-r--r--ext/pcre/pcrelib/testdata/testinput2455
-rw-r--r--ext/pcre/pcrelib/testdata/testinput2019
-rw-r--r--ext/pcre/pcrelib/testdata/testinput2126
-rw-r--r--ext/pcre/pcrelib/testdata/testinput2223
-rw-r--r--ext/pcre/pcrelib/testdata/testinput2320
-rw-r--r--ext/pcre/pcrelib/testdata/testinput2411
-rw-r--r--ext/pcre/pcrelib/testdata/testinput2544
-rw-r--r--ext/pcre/pcrelib/testdata/testinput2614
-rw-r--r--ext/pcre/pcrelib/testdata/testinput32
-rw-r--r--ext/pcre/pcrelib/testdata/testinput495
-rw-r--r--ext/pcre/pcrelib/testdata/testinput519
-rw-r--r--ext/pcre/pcrelib/testdata/testinput6180
-rw-r--r--ext/pcre/pcrelib/testdata/testinput7166
-rw-r--r--ext/pcre/pcrelib/testdata/testinput889
-rw-r--r--ext/pcre/pcrelib/testdata/testinput924
-rw-r--r--ext/pcre/pcrelib/testdata/testinputEBC121
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput1678
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput10581
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput11-16712
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput11-32712
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput11-8712
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput12179
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput1322
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput14530
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput151139
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput16121
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput17558
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput18-161026
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput18-321023
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput1988
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput22150
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput2024
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput21-16100
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput21-32100
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput22-1681
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput22-3281
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput2346
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput2413
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput2593
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput2617
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput32
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput4172
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput566
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput6339
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput7835
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput8451
-rw-r--r--ext/pcre/pcrelib/testdata/testoutput9114
-rw-r--r--ext/pcre/pcrelib/testdata/testoutputEBC182
-rw-r--r--ext/pcre/pcrelib/testdata/wintestinput391
-rw-r--r--ext/pcre/pcrelib/testdata/wintestoutput3166
-rw-r--r--ext/pcre/pcrelib/ucp.h5
104 files changed, 22111 insertions, 5746 deletions
diff --git a/ext/pcre/pcrelib/AUTHORS b/ext/pcre/pcrelib/AUTHORS
index ba4753d858..97d8c71dd6 100644
--- a/ext/pcre/pcrelib/AUTHORS
+++ b/ext/pcre/pcrelib/AUTHORS
@@ -8,7 +8,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2012 University of Cambridge
+Copyright (c) 1997-2013 University of Cambridge
All rights reserved
@@ -19,7 +19,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2010-2012 Zoltan Herczeg
+Copyright(c) 2010-2013 Zoltan Herczeg
All rights reserved.
@@ -30,7 +30,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2009-2012 Zoltan Herczeg
+Copyright(c) 2009-2013 Zoltan Herczeg
All rights reserved.
diff --git a/ext/pcre/pcrelib/ChangeLog b/ext/pcre/pcrelib/ChangeLog
index ed164fed0f..1f1e860035 100644
--- a/ext/pcre/pcrelib/ChangeLog
+++ b/ext/pcre/pcrelib/ChangeLog
@@ -1,6 +1,381 @@
ChangeLog for PCRE
------------------
+Version 8.34 15-December-2013
+-----------------------------
+
+1. Add pcre[16|32]_jit_free_unused_memory to forcibly free unused JIT
+ executable memory. Patch inspired by Carsten Klein.
+
+2. ./configure --enable-coverage defined SUPPORT_GCOV in config.h, although
+ this macro is never tested and has no effect, because the work to support
+ coverage involves only compiling and linking options and special targets in
+ the Makefile. The comment in config.h implied that defining the macro would
+ enable coverage support, which is totally false. There was also support for
+ setting this macro in the CMake files (my fault, I just copied it from
+ configure). SUPPORT_GCOV has now been removed.
+
+3. Make a small performance improvement in strlen16() and strlen32() in
+ pcretest.
+
+4. Change 36 for 8.33 left some unreachable statements in pcre_exec.c,
+ detected by the Solaris compiler (gcc doesn't seem to be able to diagnose
+ these cases). There was also one in pcretest.c.
+
+5. Cleaned up a "may be uninitialized" compiler warning in pcre_exec.c.
+
+6. In UTF mode, the code for checking whether a group could match an empty
+ string (which is used for indefinitely repeated groups to allow for
+ breaking an infinite loop) was broken when the group contained a repeated
+ negated single-character class with a character that occupied more than one
+ data item and had a minimum repetition of zero (for example, [^\x{100}]* in
+ UTF-8 mode). The effect was undefined: the group might or might not be
+ deemed as matching an empty string, or the program might have crashed.
+
+7. The code for checking whether a group could match an empty string was not
+ recognizing that \h, \H, \v, \V, and \R must match a character.
+
+8. Implemented PCRE_INFO_MATCH_EMPTY, which yields 1 if the pattern can match
+ an empty string. If it can, pcretest shows this in its information output.
+
+9. Fixed two related bugs that applied to Unicode extended grapheme clusters
+ that were repeated with a maximizing qualifier (e.g. \X* or \X{2,5}) when
+ matched by pcre_exec() without using JIT:
+
+ (a) If the rest of the pattern did not match after a maximal run of
+ grapheme clusters, the code for backing up to try with fewer of them
+ did not always back up over a full grapheme when characters that do not
+ have the modifier quality were involved, e.g. Hangul syllables.
+
+ (b) If the match point in a subject started with modifier character, and
+ there was no match, the code could incorrectly back up beyond the match
+ point, and potentially beyond the first character in the subject,
+ leading to a segfault or an incorrect match result.
+
+10. A conditional group with an assertion condition could lead to PCRE
+ recording an incorrect first data item for a match if no other first data
+ item was recorded. For example, the pattern (?(?=ab)ab) recorded "a" as a
+ first data item, and therefore matched "ca" after "c" instead of at the
+ start.
+
+11. Change 40 for 8.33 (allowing pcregrep to find empty strings) showed up a
+ bug that caused the command "echo a | ./pcregrep -M '|a'" to loop.
+
+12. The source of pcregrep now includes z/OS-specific code so that it can be
+ compiled for z/OS as part of the special z/OS distribution.
+
+13. Added the -T and -TM options to pcretest.
+
+14. The code in pcre_compile.c for creating the table of named capturing groups
+ has been refactored. Instead of creating the table dynamically during the
+ actual compiling pass, the information is remembered during the pre-compile
+ pass (on the stack unless there are more than 20 named groups, in which
+ case malloc() is used) and the whole table is created before the actual
+ compile happens. This has simplified the code (it is now nearly 150 lines
+ shorter) and prepared the way for better handling of references to groups
+ with duplicate names.
+
+15. A back reference to a named subpattern when there is more than one of the
+ same name now checks them in the order in which they appear in the pattern.
+ The first one that is set is used for the reference. Previously only the
+ first one was inspected. This change makes PCRE more compatible with Perl.
+
+16. Unicode character properties were updated from Unicode 6.3.0.
+
+17. The compile-time code for auto-possessification has been refactored, based
+ on a patch by Zoltan Herczeg. It now happens after instead of during
+ compilation. The code is cleaner, and more cases are handled. The option
+ PCRE_NO_AUTO_POSSESS is added for testing purposes, and the -O and /O
+ options in pcretest are provided to set it. It can also be set by
+ (*NO_AUTO_POSSESS) at the start of a pattern.
+
+18. The character VT has been added to the default ("C" locale) set of
+ characters that match \s and are generally treated as white space,
+ following this same change in Perl 5.18. There is now no difference between
+ "Perl space" and "POSIX space". Whether VT is treated as white space in
+ other locales depends on the locale.
+
+19. The code for checking named groups as conditions, either for being set or
+ for being recursed, has been refactored (this is related to 14 and 15
+ above). Processing unduplicated named groups should now be as fast at
+ numerical groups, and processing duplicated groups should be faster than
+ before.
+
+20. Two patches to the CMake build system, by Alexander Barkov:
+
+ (1) Replace the "source" command by "." in CMakeLists.txt because
+ "source" is a bash-ism.
+
+ (2) Add missing HAVE_STDINT_H and HAVE_INTTYPES_H to config-cmake.h.in;
+ without these the CMake build does not work on Solaris.
+
+21. Perl has changed its handling of \8 and \9. If there is no previously
+ encountered capturing group of those numbers, they are treated as the
+ literal characters 8 and 9 instead of a binary zero followed by the
+ literals. PCRE now does the same.
+
+22. Following Perl, added \o{} to specify codepoints in octal, making it
+ possible to specify values greater than 0777 and also making them
+ unambiguous.
+
+23. Perl now gives an error for missing closing braces after \x{... instead of
+ treating the string as literal. PCRE now does the same.
+
+24. RunTest used to grumble if an inappropriate test was selected explicitly,
+ but just skip it when running all tests. This make it awkward to run ranges
+ of tests when one of them was inappropriate. Now it just skips any
+ inappropriate tests, as it always did when running all tests.
+
+25. If PCRE_AUTO_CALLOUT and PCRE_UCP were set for a pattern that contained
+ character types such as \d or \w, too many callouts were inserted, and the
+ data that they returned was rubbish.
+
+26. In UCP mode, \s was not matching two of the characters that Perl matches,
+ namely NEL (U+0085) and MONGOLIAN VOWEL SEPARATOR (U+180E), though they
+ were matched by \h. The code has now been refactored so that the lists of
+ the horizontal and vertical whitespace characters used for \h and \v (which
+ are defined only in one place) are now also used for \s.
+
+27. Add JIT support for the 64 bit TileGX architecture.
+ Patch by Jiong Wang (Tilera Corporation).
+
+28. Possessive quantifiers for classes (both explicit and automatically
+ generated) now use special opcodes instead of wrapping in ONCE brackets.
+
+29. Whereas an item such as A{4}+ ignored the possessivenes of the quantifier
+ (because it's meaningless), this was not happening when PCRE_CASELESS was
+ set. Not wrong, but inefficient.
+
+30. Updated perltest.pl to add /u (force Unicode mode) when /W (use Unicode
+ properties for \w, \d, etc) is present in a test regex. Otherwise if the
+ test contains no characters greater than 255, Perl doesn't realise it
+ should be using Unicode semantics.
+
+31. Upgraded the handling of the POSIX classes [:graph:], [:print:], and
+ [:punct:] when PCRE_UCP is set so as to include the same characters as Perl
+ does in Unicode mode.
+
+32. Added the "forbid" facility to pcretest so that putting tests into the
+ wrong test files can sometimes be quickly detected.
+
+33. There is now a limit (default 250) on the depth of nesting of parentheses.
+ This limit is imposed to control the amount of system stack used at compile
+ time. It can be changed at build time by --with-parens-nest-limit=xxx or
+ the equivalent in CMake.
+
+34. Character classes such as [A-\d] or [a-[:digit:]] now cause compile-time
+ errors. Perl warns for these when in warning mode, but PCRE has no facility
+ for giving warnings.
+
+35. Change 34 for 8.13 allowed quantifiers on assertions, because Perl does.
+ However, this was not working for (?!) because it is optimized to (*FAIL),
+ for which PCRE does not allow quantifiers. The optimization is now disabled
+ when a quantifier follows (?!). I can't see any use for this, but it makes
+ things uniform.
+
+36. Perl no longer allows group names to start with digits, so I have made this
+ change also in PCRE. It simplifies the code a bit.
+
+37. In extended mode, Perl ignores spaces before a + that indicates a
+ possessive quantifier. PCRE allowed a space before the quantifier, but not
+ before the possessive +. It now does.
+
+38. The use of \K (reset reported match start) within a repeated possessive
+ group such as (a\Kb)*+ was not working.
+
+40. Document that the same character tables must be used at compile time and
+ run time, and that the facility to pass tables to pcre_exec() and
+ pcre_dfa_exec() is for use only with saved/restored patterns.
+
+41. Applied Jeff Trawick's patch CMakeLists.txt, which "provides two new
+ features for Builds with MSVC:
+
+ 1. Support pcre.rc and/or pcreposix.rc (as is already done for MinGW
+ builds). The .rc files can be used to set FileDescription and many other
+ attributes.
+
+ 2. Add an option (-DINSTALL_MSVC_PDB) to enable installation of .pdb files.
+ This allows higher-level build scripts which want .pdb files to avoid
+ hard-coding the exact files needed."
+
+42. Added support for [[:<:]] and [[:>:]] as used in the BSD POSIX library to
+ mean "start of word" and "end of word", respectively, as a transition aid.
+
+43. A minimizing repeat of a class containing codepoints greater than 255 in
+ non-UTF 16-bit or 32-bit modes caused an internal error when PCRE was
+ compiled to use the heap for recursion.
+
+44. Got rid of some compiler warnings for unused variables when UTF but not UCP
+ is configured.
+
+
+Version 8.33 28-May-2013
+------------------------
+
+1. Added 'U' to some constants that are compared to unsigned integers, to
+ avoid compiler signed/unsigned warnings. Added (int) casts to unsigned
+ variables that are added to signed variables, to ensure the result is
+ signed and can be negated.
+
+2. Applied patch by Daniel Richard G for quashing MSVC warnings to the
+ CMake config files.
+
+3. Revise the creation of config.h.generic so that all boolean macros are
+ #undefined, whereas non-boolean macros are #ifndef/#endif-ed. This makes
+ overriding via -D on the command line possible.
+
+4. Changing the definition of the variable "op" in pcre_exec.c from pcre_uchar
+ to unsigned int is reported to make a quite noticeable speed difference in
+ a specific Windows environment. Testing on Linux did also appear to show
+ some benefit (and it is clearly not harmful). Also fixed the definition of
+ Xop which should be unsigned.
+
+5. Related to (4), changing the definition of the intermediate variable cc
+ in repeated character loops from pcre_uchar to pcre_uint32 also gave speed
+ improvements.
+
+6. Fix forward search in JIT when link size is 3 or greater. Also removed some
+ unnecessary spaces.
+
+7. Adjust autogen.sh and configure.ac to lose warnings given by automake 1.12
+ and later.
+
+8. Fix two buffer over read issues in 16 and 32 bit modes. Affects JIT only.
+
+9. Optimizing fast_forward_start_bits in JIT.
+
+10. Adding support for callouts in JIT, and fixing some issues revealed
+ during this work. Namely:
+
+ (a) Unoptimized capturing brackets incorrectly reset on backtrack.
+
+ (b) Minimum length was not checked before the matching is started.
+
+11. The value of capture_last that is passed to callouts was incorrect in some
+ cases when there was a capture on one path that was subsequently abandoned
+ after a backtrack. Also, the capture_last value is now reset after a
+ recursion, since all captures are also reset in this case.
+
+12. The interpreter no longer returns the "too many substrings" error in the
+ case when an overflowing capture is in a branch that is subsequently
+ abandoned after a backtrack.
+
+13. In the pathological case when an offset vector of size 2 is used, pcretest
+ now prints out the matched string after a yield of 0 or 1.
+
+14. Inlining subpatterns in recursions, when certain conditions are fulfilled.
+ Only supported by the JIT compiler at the moment.
+
+15. JIT compiler now supports 32 bit Macs thanks to Lawrence Velazquez.
+
+16. Partial matches now set offsets[2] to the "bumpalong" value, that is, the
+ offset of the starting point of the matching process, provided the offsets
+ vector is large enough.
+
+17. The \A escape now records a lookbehind value of 1, though its execution
+ does not actually inspect the previous character. This is to ensure that,
+ in partial multi-segment matching, at least one character from the old
+ segment is retained when a new segment is processed. Otherwise, if there
+ are no lookbehinds in the pattern, \A might match incorrectly at the start
+ of a new segment.
+
+18. Added some #ifdef __VMS code into pcretest.c to help VMS implementations.
+
+19. Redefined some pcre_uchar variables in pcre_exec.c as pcre_uint32; this
+ gives some modest performance improvement in 8-bit mode.
+
+20. Added the PCRE-specific property \p{Xuc} for matching characters that can
+ be expressed in certain programming languages using Universal Character
+ Names.
+
+21. Unicode validation has been updated in the light of Unicode Corrigendum #9,
+ which points out that "non characters" are not "characters that may not
+ appear in Unicode strings" but rather "characters that are reserved for
+ internal use and have only local meaning".
+
+22. When a pattern was compiled with automatic callouts (PCRE_AUTO_CALLOUT) and
+ there was a conditional group that depended on an assertion, if the
+ assertion was false, the callout that immediately followed the alternation
+ in the condition was skipped when pcre_exec() was used for matching.
+
+23. Allow an explicit callout to be inserted before an assertion that is the
+ condition for a conditional group, for compatibility with automatic
+ callouts, which always insert a callout at this point.
+
+24. In 8.31, (*COMMIT) was confined to within a recursive subpattern. Perl also
+ confines (*SKIP) and (*PRUNE) in the same way, and this has now been done.
+
+25. (*PRUNE) is now supported by the JIT compiler.
+
+26. Fix infinite loop when /(?<=(*SKIP)ac)a/ is matched against aa.
+
+27. Fix the case where there are two or more SKIPs with arguments that may be
+ ignored.
+
+28. (*SKIP) is now supported by the JIT compiler.
+
+29. (*THEN) is now supported by the JIT compiler.
+
+30. Update RunTest with additional test selector options.
+
+31. The way PCRE handles backtracking verbs has been changed in two ways.
+
+ (1) Previously, in something like (*COMMIT)(*SKIP), COMMIT would override
+ SKIP. Now, PCRE acts on whichever backtracking verb is reached first by
+ backtracking. In some cases this makes it more Perl-compatible, but Perl's
+ rather obscure rules do not always do the same thing.
+
+ (2) Previously, backtracking verbs were confined within assertions. This is
+ no longer the case for positive assertions, except for (*ACCEPT). Again,
+ this sometimes improves Perl compatibility, and sometimes does not.
+
+32. A number of tests that were in test 2 because Perl did things differently
+ have been moved to test 1, because either Perl or PCRE has changed, and
+ these tests are now compatible.
+
+32. Backtracking control verbs are now handled in the same way in JIT and
+ interpreter.
+
+33. An opening parenthesis in a MARK/PRUNE/SKIP/THEN name in a pattern that
+ contained a forward subroutine reference caused a compile error.
+
+34. Auto-detect and optimize limited repetitions in JIT.
+
+35. Implement PCRE_NEVER_UTF to lock out the use of UTF, in particular,
+ blocking (*UTF) etc.
+
+36. In the interpreter, maximizing pattern repetitions for characters and
+ character types now use tail recursion, which reduces stack usage.
+
+37. The value of the max lookbehind was not correctly preserved if a compiled
+ and saved regex was reloaded on a host of different endianness.
+
+38. Implemented (*LIMIT_MATCH) and (*LIMIT_RECURSION). As part of the extension
+ of the compiled pattern block, expand the flags field from 16 to 32 bits
+ because it was almost full.
+
+39. Try madvise first before posix_madvise.
+
+40. Change 7 for PCRE 7.9 made it impossible for pcregrep to find empty lines
+ with a pattern such as ^$. It has taken 4 years for anybody to notice! The
+ original change locked out all matches of empty strings. This has been
+ changed so that one match of an empty string per line is recognized.
+ Subsequent searches on the same line (for colouring or for --only-matching,
+ for example) do not recognize empty strings.
+
+41. Applied a user patch to fix a number of spelling mistakes in comments.
+
+42. Data lines longer than 65536 caused pcretest to crash.
+
+43. Clarified the data type for length and startoffset arguments for pcre_exec
+ and pcre_dfa_exec in the function-specific man pages, where they were
+ explicitly stated to be in bytes, never having been updated. I also added
+ some clarification to the pcreapi man page.
+
+44. A call to pcre_dfa_exec() with an output vector size less than 2 caused
+ a segmentation fault.
+
+
Version 8.32 30-November-2012
-----------------------------
@@ -1508,7 +1883,8 @@ Version 7.9 11-Apr-09
7. A pattern that could match an empty string could cause pcregrep to loop; it
doesn't make sense to accept an empty string match in pcregrep, so I have
locked it out (using PCRE's PCRE_NOTEMPTY option). By experiment, this
- seems to be how GNU grep behaves.
+ seems to be how GNU grep behaves. [But see later change 40 for release
+ 8.33.]
8. The pattern (?(?=.*b)b|^) was incorrectly compiled as "match must be at
start or after a newline", because the conditional assertion was not being
diff --git a/ext/pcre/pcrelib/HACKING b/ext/pcre/pcrelib/HACKING
index a90ddf8797..691b7a14e5 100644
--- a/ext/pcre/pcrelib/HACKING
+++ b/ext/pcre/pcrelib/HACKING
@@ -54,12 +54,12 @@ Support for 16-bit and 32-bit data strings
From release 8.30, PCRE supports 16-bit as well as 8-bit data strings; and from
release 8.32, PCRE supports 32-bit data strings. The library can be compiled
-in any combination of 8-bit, 16-bit or 32-bit modes, creating different
-libraries. In the description that follows, the word "short" is
-used for a 16-bit data quantity, and the word "unit" is used for a quantity
-that is a byte in 8-bit mode, a short in 16-bit mode and a 32-bit unsigned
-integer in 32-bit mode. However, so as not to over-complicate the text, the
-names of PCRE functions are given in 8-bit form only.
+in any combination of 8-bit, 16-bit or 32-bit modes, creating up to three
+different libraries. In the description that follows, the word "short" is used
+for a 16-bit data quantity, and the word "unit" is used for a quantity that is
+a byte in 8-bit mode, a short in 16-bit mode and a 32-bit word in 32-bit mode.
+However, so as not to over-complicate the text, the names of PCRE functions are
+given in 8-bit form only.
Computing the memory requirement: how it was
@@ -94,6 +94,11 @@ runs more slowly than before (30% or more, depending on the pattern) because it
is doing a full analysis of the pattern. My hope was that this would not be a
big issue, and in the event, nobody has commented on it.
+At release 8.34, a limit on the nesting depth of parentheses was re-introduced
+(default 250, settable at build time) so as to put a limit on the amount of
+system stack used by pcre_compile(). This is a safety feature for environments
+with small stacks where the patterns are provided by users.
+
Traditional matching function
-----------------------------
@@ -120,29 +125,30 @@ facilities are available, and those that are do not always work in quite the
same way. See the user documentation for details.
The algorithm that is used for pcre_dfa_exec() is not a traditional FSM,
-because it may have a number of states active at one time. More work would be
-needed at compile time to produce a traditional FSM where only one state is
-ever active at once. I believe some other regex matchers work this way.
+because it may have a number of states active at one time. More work would be
+needed at compile time to produce a traditional FSM where only one state is
+ever active at once. I believe some other regex matchers work this way. JIT
+support is not available for this kind of matching.
Changeable options
------------------
-The /i, /m, or /s options (PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL) may
-change in the middle of patterns. From PCRE 8.13, their processing is handled
-entirely at compile time by generating different opcodes for the different
-settings. The runtime functions do not need to keep track of an options state
-any more.
+The /i, /m, or /s options (PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and some
+others) may change in the middle of patterns. From PCRE 8.13, their processing
+is handled entirely at compile time by generating different opcodes for the
+different settings. The runtime functions do not need to keep track of an
+options state any more.
Format of compiled patterns
---------------------------
-The compiled form of a pattern is a vector of units (bytes in 8-bit mode, or
-shorts in 16-bit mode, 32-bit unsigned integers in 32-bit mode), containing
-items of variable length. The first unit in an item contains an opcode, and
-the length of the item is either implicit in the opcode or contained in the
-data that follows it.
+The compiled form of a pattern is a vector of unsigned units (bytes in 8-bit
+mode, shorts in 16-bit mode, 32-bit words in 32-bit mode), containing items of
+variable length. The first unit in an item contains an opcode, and the length
+of the item is either implicit in the opcode or contained in the data that
+follows it.
In many cases listed below, LINK_SIZE data values are specified for offsets
within the compiled pattern. LINK_SIZE always specifies a number of bytes. The
@@ -151,8 +157,10 @@ default value for LINK_SIZE is 2, but PCRE can be compiled to use 3-byte or
LINK_SIZE values are available only in 8-bit mode.) Specifing a LINK_SIZE
larger than 2 is necessary only when patterns whose compiled length is greater
than 64K are going to be processed. In this description, we assume the "normal"
-compilation options. Data values that are counts (e.g. for quantifiers) are
-always just two bytes long (one short in 16-bit mode).
+compilation options. Data values that are counts (e.g. quantifiers) are two
+bytes long in 8-bit mode (most significant byte first), or one unit in 16-bit
+and 32-bit modes.
+
Opcodes with no following data
------------------------------
@@ -162,7 +170,7 @@ These items are all just one unit long
OP_END end of pattern
OP_ANY match any one character other than newline
OP_ALLANY match any one character, including newline
- OP_ANYBYTE match any single byte, even in UTF-8 mode
+ OP_ANYBYTE match any single unit, even in UTF-8/16 mode
OP_SOD match start of data: \A
OP_SOM, start of match (subject + offset): \G
OP_SET_SOM, set start of match (\K)
@@ -180,28 +188,33 @@ These items are all just one unit long
OP_VSPACE \v
OP_NOT_WORDCHAR \W
OP_WORDCHAR \w
- OP_EODN match end of data or \n at end: \Z
+ OP_EODN match end of data or newline at end: \Z
OP_EOD match end of data: \z
OP_DOLL $ (end of data, or before final newline)
OP_DOLLM $ multiline mode (end of data or before newline)
- OP_EXTUNI match an extended Unicode character
+ OP_EXTUNI match an extended Unicode grapheme cluster
OP_ANYNL match any Unicode newline sequence
+ OP_ASSERT_ACCEPT )
OP_ACCEPT ) These are Perl 5.10's "backtracking control
OP_COMMIT ) verbs". If OP_ACCEPT is inside capturing
OP_FAIL ) parentheses, it may be preceded by one or more
- OP_PRUNE ) OP_CLOSE, followed by a 2-byte number,
- OP_SKIP ) indicating which parentheses must be closed.
+ OP_PRUNE ) OP_CLOSE, each followed by a count that
+ OP_SKIP ) indicates which parentheses must be closed.
+ OP_THEN )
+
+OP_ASSERT_ACCEPT is used when (*ACCEPT) is encountered within an assertion.
+This ends the assertion, not the entire pattern match.
-Backtracking control verbs with (optional) data
------------------------------------------------
+Backtracking control verbs with optional data
+---------------------------------------------
(*THEN) without an argument generates the opcode OP_THEN and no following data.
OP_MARK is followed by the mark name, preceded by a one-unit length, and
followed by a binary zero. For (*PRUNE), (*SKIP), and (*THEN) with arguments,
the opcodes OP_PRUNE_ARG, OP_SKIP_ARG, and OP_THEN_ARG are used, with the name
-following in the same format.
+following in the same format as OP_MARK.
Matching literal characters
@@ -212,6 +225,10 @@ casefully. For caseless matching, OP_CHARI is used. In UTF-8 or UTF-16 modes,
the character may be more than one unit long. In UTF-32 mode, characters
are always exactly one unit long.
+If there is only one character in a character class, OP_CHAR or OP_CHARI is
+used for a positive class, and OP_NOT or OP_NOTI for a negative one (that is,
+for something like [^a]).
+
Repeating single characters
---------------------------
@@ -232,10 +249,9 @@ following opcodes, which come in caseful and caseless versions:
Each opcode is followed by the character that is to be repeated. In ASCII mode,
these are two-unit items; in UTF-8 or UTF-16 modes, the length is variable; in
-UTF-32 mode these are one-unit items.
-Those with "MIN" in their names are the minimizing versions. Those with "POS"
-in their names are possessive versions. Other repeats make use of these
-opcodes:
+UTF-32 mode these are one-unit items. Those with "MIN" in their names are the
+minimizing versions. Those with "POS" in their names are possessive versions.
+Other repeats make use of these opcodes:
Caseful Caseless
OP_UPTO OP_UPTOI
@@ -243,10 +259,15 @@ opcodes:
OP_POSUPTO OP_POSUPTOI
OP_EXACT OP_EXACTI
-Each of these is followed by a two-byte (one short) count (most significant
-byte first in 8-bit mode) and then the repeated character. OP_UPTO matches from
-0 to the given number. A repeat with a non-zero minimum and a fixed maximum is
-coded as an OP_EXACT followed by an OP_UPTO (or OP_MINUPTO or OPT_POSUPTO).
+Each of these is followed by a count and then the repeated character. OP_UPTO
+matches from 0 to the given number. A repeat with a non-zero minimum and a
+fixed maximum is coded as an OP_EXACT followed by an OP_UPTO (or OP_MINUPTO or
+OPT_POSUPTO).
+
+Another set of matching repeating opcodes (called OP_NOTSTAR, OP_NOTSTARI,
+etc.) are used for repeated, negated, single-character classes such as [^a]*.
+The normal single-character opcodes (OP_STAR, etc.) are used for repeated
+positive single-character classes.
Repeating character types
@@ -277,7 +298,10 @@ Match by Unicode property
OP_PROP and OP_NOTPROP are used for positive and negative matches of a
character by testing its Unicode property (the \p and \P escape sequences).
Each is followed by two units that encode the desired property as a type and a
-value.
+value. The types are a set of #defines of the form PT_xxx, and the values are
+enumerations of the form ucp_xx, defined in the ucp.h source file. The value is
+relevant only for PT_GC (General Category), PT_PC (Particular Category), and
+PT_SC (Script).
Repeats of these items use the OP_TYPESTAR etc. set of opcodes, followed by
three units: OP_PROP or OP_NOTPROP, and then the desired property type and
@@ -287,67 +311,88 @@ value.
Character classes
-----------------
-If there is only one character in the class, OP_CHAR or OP_CHARI is used for a
+If there is only one character in a class, OP_CHAR or OP_CHARI is used for a
positive class, and OP_NOT or OP_NOTI for a negative one (that is, for
something like [^a]).
-Another set of 13 repeating opcodes (called OP_NOTSTAR etc.) are used for
-repeated, negated, single-character classes. The normal single-character
-opcodes (OP_STAR, etc.) are used for repeated positive single-character
-classes.
+A set of repeating opcodes (called OP_NOTSTAR etc.) are used for repeated,
+negated, single-character classes. The normal single-character opcodes
+(OP_STAR, etc.) are used for repeated positive single-character classes.
-When there is more than one character in a class and all the characters are
+When there is more than one character in a class, and all the code points are
less than 256, OP_CLASS is used for a positive class, and OP_NCLASS for a
-negative one. In either case, the opcode is followed by a 32-byte (16-short)
-bit map containing a 1 bit for every character that is acceptable. The bits are
-counted from the least significant end of each unit. In caseless mode, bits for
-both cases are set.
+negative one. In either case, the opcode is followed by a 32-byte (16-short,
+8-word) bit map containing a 1 bit for every character that is acceptable. The
+bits are counted from the least significant end of each unit. In caseless mode,
+bits for both cases are set.
+
+The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8/16/32
+mode, subject characters with values greater than 255 can be handled correctly.
+For OP_CLASS they do not match, whereas for OP_NCLASS they do.
+
+For classes containing characters with values greater than 255 or that contain
+\p or \P, OP_XCLASS is used. It optionally uses a bit map if any code points
+are less than 256, followed by a list of pairs (for a range) and single
+characters. In caseless mode, both cases are explicitly listed.
-The reason for having both OP_CLASS and OP_NCLASS is so that, in UTF-8/16/32 mode,
-subject characters with values greater than 255 can be handled correctly. For
-OP_CLASS they do not match, whereas for OP_NCLASS they do.
+OP_XCLASS is followed by a unit containing flag bits: XCL_NOT indicates that
+this is a negative class, and XCL_MAP indicates that a bit map is present.
+There follows the bit map, if XCL_MAP is set, and then a sequence of items
+coded as follows:
-For classes containing characters with values greater than 255, OP_XCLASS is
-used. It optionally uses a bit map (if any characters lie within it), followed
-by a list of pairs (for a range) and single characters. In caseless mode, both
-cases are explicitly listed. There is a flag character than indicates whether
-it is a positive or a negative class.
+ XCL_END marks the end of the list
+ XCL_SINGLE one character follows
+ XCL_RANGE two characters follow
+ XCL_PROP a Unicode property (type, value) follows
+ XCL_NOTPROP a Unicode property (type, value) follows
+
+If a range starts with a code point less than 256 and ends with one greater
+than 256, an XCL_RANGE item is used, without setting any bits in the bit map.
+This means that if no other items in the class set bits in the map, a map is
+not needed.
Back references
---------------
-OP_REF (caseful) or OP_REFI (caseless) is followed by two bytes (one short)
-containing the reference number.
+OP_REF (caseful) or OP_REFI (caseless) is followed by a count containing the
+reference number if the reference is to a unique capturing group (either by
+number or by name). When named groups are used, there may be more than one
+group with the same name. In this case, a reference by name generates OP_DNREF
+or OP_DNREFI. These are followed by two counts: the index (not the byte offset)
+in the group name table of the first entry for the requred name, followed by
+the number of groups with the same name.
Repeating character classes and back references
-----------------------------------------------
Single-character classes are handled specially (see above). This section
-applies to OP_CLASS and OP_REF[I]. In both cases, the repeat information
-follows the base item. The matching code looks at the following opcode to see
-if it is one of
+applies to other classes and also to back references. In both cases, the repeat
+information follows the base item. The matching code looks at the following
+opcode to see if it is one of
OP_CRSTAR
OP_CRMINSTAR
+ OP_CRPOSSTAR
OP_CRPLUS
OP_CRMINPLUS
+ OP_CRPOSPLUS
OP_CRQUERY
OP_CRMINQUERY
+ OP_CRPOSQUERY
OP_CRRANGE
OP_CRMINRANGE
+ OP_CRPOSRANGE
-All but the last two are just single-unit items. The others are followed by
-four bytes (two shorts) of data, comprising the minimum and maximum repeat
-counts. There are no special possessive opcodes for these repeats; a possessive
-repeat is compiled into an atomic group.
+All but the last three are single-unit items, with no data. The others are
+followed by the minimum and maximum repeat counts.
Brackets and alternation
------------------------
-A pair of non-capturing (round) brackets is wrapped round each expression at
+A pair of non-capturing round brackets is wrapped round each expression at
compile time, so alternation always happens in the context of brackets.
[Note for North Americans: "bracket" to some English speakers, including
@@ -364,20 +409,20 @@ A bracket opcode is followed by LINK_SIZE bytes which give the offset to the
next alternative OP_ALT or, if there aren't any branches, to the matching
OP_KET opcode. Each OP_ALT is followed by LINK_SIZE bytes giving the offset to
the next one, or to the OP_KET opcode. For capturing brackets, the bracket
-number immediately follows the offset, always as a 2-byte (one short) item.
+number is a count that immediately follows the offset.
-OP_KET is used for subpatterns that do not repeat indefinitely, and
-OP_KETRMIN and OP_KETRMAX are used for indefinite repetitions, minimally or
-maximally respectively (see below for possessive repetitions). All three are
-followed by LINK_SIZE bytes giving (as a positive number) the offset back to
-the matching bracket opcode.
+OP_KET is used for subpatterns that do not repeat indefinitely, and OP_KETRMIN
+and OP_KETRMAX are used for indefinite repetitions, minimally or maximally
+respectively (see below for possessive repetitions). All three are followed by
+LINK_SIZE bytes giving (as a positive number) the offset back to the matching
+bracket opcode.
If a subpattern is quantified such that it is permitted to match zero times, it
is preceded by one of OP_BRAZERO, OP_BRAMINZERO, or OP_SKIPZERO. These are
single-unit opcodes that tell the matcher that skipping the following
subpattern entirely is a valid branch. In the case of the first two, not
skipping the pattern is also valid (greedy and non-greedy). The third is used
-when a pattern has the quantifier {0,0}. It cannot be entirely discarded,
+when a pattern has the quantifier {0,0}. It cannot be entirely discarded,
because it may be called as a subroutine from elsewhere in the regex.
A subpattern with an indefinite maximum repetition is replicated in the
@@ -397,6 +442,7 @@ final replication is changed to OP_SBRA or OP_SCBRA. This tells the matcher
that it needs to check for matching an empty string when it hits OP_KETRMIN or
OP_KETRMAX, and if so, to break the loop.
+
Possessive brackets
-------------------
@@ -407,26 +453,34 @@ of OP_SCBRA. The end of such a group is marked by OP_KETRPOS. If the minimum
repetition is zero, the group is preceded by OP_BRAPOSZERO.
-Assertions
-----------
+Once-only (atomic) groups
+-------------------------
-Forward assertions are just like other subpatterns, but starting with one of
-the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes
-OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion
-is OP_REVERSE, followed by a two byte (one short) count of the number of
-characters to move back the pointer in the subject string. In ASCII mode, the
-count is a number of units, but in UTF-8/16 mode each character may occupy more
-than one unit; in UTF-32 mode each character occupies exactly one unit.
-A separate count is present in each alternative of a lookbehind
-assertion, allowing them to have different fixed lengths.
+These are just like other subpatterns, but they start with the opcode
+OP_ONCE or OP_ONCE_NC. The former is used when there are no capturing brackets
+within the atomic group; the latter when there are. The distinction is needed
+for when there is a backtrack to before the group - any captures within the
+group must be reset, so it is necessary to retain backtracking points inside
+the group even after it is complete in order to do this. When there are no
+captures in an atomic group, all the backtracking can be discarded when it is
+complete. This is more efficient, and also uses less stack.
+The check for matching an empty string in an unbounded repeat is handled
+entirely at runtime, so there are just these two opcodes for atomic groups.
-Once-only (atomic) subpatterns
-------------------------------
-These are also just like other subpatterns, but they start with the opcode
-OP_ONCE. The check for matching an empty string in an unbounded repeat is
-handled entirely at runtime, so there is just this one opcode.
+Assertions
+----------
+
+Forward assertions are also just like other subpatterns, but starting with one
+of the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes
+OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion
+is OP_REVERSE, followed by a count of the number of characters to move back the
+pointer in the subject string. In ASCII mode, the count is a number of units,
+but in UTF-8/16 mode each character may occupy more than one unit; in UTF-32
+mode each character occupies exactly one unit. A separate count is present in
+each alternative of a lookbehind assertion, allowing them to have different
+fixed lengths.
Conditional subpatterns
@@ -435,28 +489,29 @@ Conditional subpatterns
These are like other subpatterns, but they start with the opcode OP_COND, or
OP_SCOND for one that might match an empty string in an unbounded repeat. If
the condition is a back reference, this is stored at the start of the
-subpattern using the opcode OP_CREF followed by two bytes (one short)
-containing the reference number. OP_NCREF is used instead if the reference was
-generated by name (so that the runtime code knows to check for duplicate
-names).
+subpattern using the opcode OP_CREF followed by a count containing the
+reference number, provided that the reference is to a unique capturing group.
+If the reference was by name and there is more than one group with that name,
+OP_DNCREF is used instead. It is followed by two counts: the index in the group
+names table, and the number of groups with the same name.
If the condition is "in recursion" (coded as "(?(R)"), or "in recursion of
group x" (coded as "(?(Rx)"), the group number is stored at the start of the
-subpattern using the opcode OP_RREF or OP_NRREF (cf OP_NCREF), and a value of
-zero for "the whole pattern". For a DEFINE condition, just the single unit
-OP_DEF is used (it has no associated data). Otherwise, a conditional subpattern
-always starts with one of the assertions.
+subpattern using the opcode OP_RREF (with a value of zero for "the whole
+pattern") or OP_DNRREF (with data as for OP_DNCREF). For a DEFINE condition,
+just the single unit OP_DEF is used (it has no associated data). Otherwise, a
+conditional subpattern always starts with one of the assertions.
Recursion
---------
Recursion either matches the current regex, or some subexpression. The opcode
-OP_RECURSE is followed by an value which is the offset to the starting bracket
-from the start of the whole pattern. From release 6.5, OP_RECURSE is
-automatically wrapped inside OP_ONCE brackets (because otherwise some patterns
-broke it). OP_RECURSE is also used for "subroutine" calls, even though they
-are not strictly a recursion.
+OP_RECURSE is followed by aLINK_SIZE value that is the offset to the starting
+bracket from the start of the whole pattern. From release 6.5, OP_RECURSE is
+automatically wrapped inside OP_ONCE brackets, because otherwise some patterns
+broke it. OP_RECURSE is also used for "subroutine" calls, even though they are
+not strictly a recursion.
Callout
@@ -464,10 +519,10 @@ Callout
OP_CALLOUT is followed by one unit of data that holds a callout number in the
range 0 to 254 for manual callouts, or 255 for an automatic callout. In both
-cases there follows a two-byte (one short) value giving the offset in the
-pattern to the start of the following item, and another two-byte (one short)
-item giving the length of the next item.
-
+cases there follows a count giving the offset in the pattern string to the
+start of the following item, and another count giving the length of this item.
+These values make is possible for pcretest to output useful tracing information
+using automatic callouts.
Philip Hazel
-February 2012
+November 2013
diff --git a/ext/pcre/pcrelib/LICENCE b/ext/pcre/pcrelib/LICENCE
index 5ce31a828d..3aff6a62c0 100644
--- a/ext/pcre/pcrelib/LICENCE
+++ b/ext/pcre/pcrelib/LICENCE
@@ -24,7 +24,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2012 University of Cambridge
+Copyright (c) 1997-2013 University of Cambridge
All rights reserved.
@@ -35,7 +35,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2010-2012 Zoltan Herczeg
+Copyright(c) 2010-2013 Zoltan Herczeg
All rights reserved.
@@ -46,7 +46,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2009-2012 Zoltan Herczeg
+Copyright(c) 2009-2013 Zoltan Herczeg
All rights reserved.
diff --git a/ext/pcre/pcrelib/NEWS b/ext/pcre/pcrelib/NEWS
index 082139f222..5f52f15346 100644
--- a/ext/pcre/pcrelib/NEWS
+++ b/ext/pcre/pcrelib/NEWS
@@ -1,6 +1,77 @@
News about PCRE releases
------------------------
+Release 8.34 15-December-2013
+-----------------------------
+
+As well as fixing the inevitable bugs, performance has been improved by
+refactoring and extending the amount of "auto-possessification" that PCRE does.
+Other notable changes:
+
+. Implemented PCRE_INFO_MATCH_EMPTY, which yields 1 if the pattern can match
+ an empty string. If it can, pcretest shows this in its information output.
+
+. A back reference to a named subpattern when there is more than one of the
+ same name now checks them in the order in which they appear in the pattern.
+ The first one that is set is used for the reference. Previously only the
+ first one was inspected. This change makes PCRE more compatible with Perl.
+
+. Unicode character properties were updated from Unicode 6.3.0.
+
+. The character VT has been added to the set of characters that match \s and
+ are generally treated as white space, following this same change in Perl
+ 5.18. There is now no difference between "Perl space" and "POSIX space".
+
+. Perl has changed its handling of \8 and \9. If there is no previously
+ encountered capturing group of those numbers, they are treated as the
+ literal characters 8 and 9 instead of a binary zero followed by the
+ literals. PCRE now does the same.
+
+. Following Perl, added \o{} to specify codepoints in octal, making it
+ possible to specify values greater than 0777 and also making them
+ unambiguous.
+
+. In UCP mode, \s was not matching two of the characters that Perl matches,
+ namely NEL (U+0085) and MONGOLIAN VOWEL SEPARATOR (U+180E), though they
+ were matched by \h.
+
+. Add JIT support for the 64 bit TileGX architecture.
+
+. Upgraded the handling of the POSIX classes [:graph:], [:print:], and
+ [:punct:] when PCRE_UCP is set so as to include the same characters as Perl
+ does in Unicode mode.
+
+. Perl no longer allows group names to start with digits, so I have made this
+ change also in PCRE.
+
+. Added support for [[:<:]] and [[:>:]] as used in the BSD POSIX library to
+ mean "start of word" and "end of word", respectively, as a transition aid.
+
+
+Release 8.33 28-May-2013
+--------------------------
+
+A number of bugs are fixed, and some performance improvements have been made.
+There are also some new features, of which these are the most important:
+
+. The behaviour of the backtracking verbs has been rationalized and
+ documented in more detail.
+
+. JIT now supports callouts and all of the backtracking verbs.
+
+. Unicode validation has been updated in the light of Unicode Corrigendum #9,
+ which points out that "non characters" are not "characters that may not
+ appear in Unicode strings" but rather "characters that are reserved for
+ internal use and have only local meaning".
+
+. (*LIMIT_MATCH=d) and (*LIMIT_RECURSION=d) have been added so that the
+ creator of a pattern can specify lower (but not higher) limits for the
+ matching process.
+
+. The PCRE_NEVER_UTF option is available to prevent pattern-writers from using
+ the (*UTF) feature, as this could be a security issue.
+
+
Release 8.32 30-November-2012
-----------------------------
diff --git a/ext/pcre/pcrelib/README b/ext/pcre/pcrelib/README
index a2c3d9b31c..51197df721 100644
--- a/ext/pcre/pcrelib/README
+++ b/ext/pcre/pcrelib/README
@@ -9,8 +9,10 @@ from:
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.zip
There is a mailing list for discussion about the development of PCRE at
+pcre-dev@exim.org. You can access the archives and subscribe or manage your
+subscription here:
- pcre-dev@exim.org
+ https://lists.exim.org/mailman/listinfo/pcre-dev
Please read the NEWS file if you are upgrading from a previous release.
The contents of this README file are:
@@ -25,6 +27,8 @@ The contents of this README file are:
Shared libraries
Cross-compiling using autotools
Using HP's ANSI C++ compiler (aCC)
+ Compiling in Tru64 using native compilers
+ Using Sun's compilers for Solaris
Using PCRE from MySQL
Making new tarballs
Testing PCRE
@@ -35,10 +39,10 @@ The contents of this README file are:
The PCRE APIs
-------------
-PCRE is written in C, and it has its own API. There are three sets of functions,
-one for the 8-bit library, which processes strings of bytes, one for the
-16-bit library, which processes strings of 16-bit values, and one for the 32-bit
-library, which processes strings of 32-bit values. The distribution also
+PCRE is written in C, and it has its own API. There are three sets of
+functions, one for the 8-bit library, which processes strings of bytes, one for
+the 16-bit library, which processes strings of 16-bit values, and one for the
+32-bit library, which processes strings of 32-bit values. The distribution also
includes a set of C++ wrapper functions (see the pcrecpp man page for details),
courtesy of Google Inc., which can be used to call the 8-bit PCRE library from
C++.
@@ -110,6 +114,11 @@ contributions provided support for compiling PCRE on various flavours of
Windows (I myself do not use Windows). Nowadays there is more Windows support
in the standard distribution, so these contibutions have been archived.
+A PCRE user maintains downloadable Windows binaries of the pcregrep and
+pcretest programs here:
+
+ http://www.rexegg.com/pcregrep-pcretest.html
+
Building PCRE on non-Unix-like systems
--------------------------------------
@@ -260,9 +269,17 @@ library. They are also documented in the pcrebuild man page.
on the "configure" command.
-. PCRE has a counter that can be set to limit the amount of resources it uses.
- If the limit is exceeded during a match, the match fails. The default is ten
- million. You can change the default by setting, for example,
+. PCRE has a counter that limits the depth of nesting of parentheses in a
+ pattern. This limits the amount of system stack that a pattern uses when it
+ is compiled. The default is 250, but you can change it by setting, for
+ example,
+
+ --with-parens-nest-limit=500
+
+. PCRE has a counter that can be set to limit the amount of resources it uses
+ when matching a pattern. If the limit is exceeded during a match, the match
+ fails. The default is ten million. You can change the default by setting, for
+ example,
--with-match-limit=500000
@@ -342,7 +359,8 @@ library. They are also documented in the pcrebuild man page.
report is generated by running "make coverage". If ccache is installed on
your system, it must be disabled when building PCRE for coverage reporting.
You can do this by setting the environment variable CCACHE_DISABLE=1 before
- running "make" to build PCRE.
+ running "make" to build PCRE. There is more information about coverage
+ reporting in the "pcrebuild" documentation.
. The pcregrep program currently supports only 8-bit data files, and so
requires the 8-bit PCRE library. It is possible to compile pcregrep to use
@@ -575,6 +593,27 @@ running the "configure" script:
CXXLDFLAGS="-lstd_v2 -lCsup_v2"
+Compiling in Tru64 using native compilers
+-----------------------------------------
+
+The following error may occur when compiling with native compilers in the Tru64
+operating system:
+
+ CXX libpcrecpp_la-pcrecpp.lo
+cxx: Error: /usr/lib/cmplrs/cxx/V7.1-006/include/cxx/iosfwd, line 58: #error
+ directive: "cannot include iosfwd -- define __USE_STD_IOSTREAM to
+ override default - see section 7.1.2 of the C++ Using Guide"
+#error "cannot include iosfwd -- define __USE_STD_IOSTREAM to override default
+- see section 7.1.2 of the C++ Using Guide"
+
+This may be followed by other errors, complaining that 'namespace "std" has no
+member'. The solution to this is to add the line
+
+#define __USE_STD_IOSTREAM 1
+
+to the config.h file.
+
+
Using Sun's compilers for Solaris
---------------------------------
@@ -624,27 +663,40 @@ NON-AUTOTOOLS-BUILD.
The RunTest script runs the pcretest test program (which is documented in its
own man page) on each of the relevant testinput files in the testdata
directory, and compares the output with the contents of the corresponding
-testoutput files. Some tests are relevant only when certain build-time options
-were selected. For example, the tests for UTF-8/16/32 support are run only if
---enable-utf was used. RunTest outputs a comment when it skips a test.
+testoutput files. RunTest uses a file called testtry to hold the main output
+from pcretest. Other files whose names begin with "test" are used as working
+files in some tests.
+
+Some tests are relevant only when certain build-time options were selected. For
+example, the tests for UTF-8/16/32 support are run only if --enable-utf was
+used. RunTest outputs a comment when it skips a test.
Many of the tests that are not skipped are run up to three times. The second
run forces pcre_study() to be called for all patterns except for a few in some
tests that are marked "never study" (see the pcretest program for how this is
done). If JIT support is available, the non-DFA tests are run a third time,
this time with a forced pcre_study() with the PCRE_STUDY_JIT_COMPILE option.
+This testing can be suppressed by putting "nojit" on the RunTest command line.
The entire set of tests is run once for each of the 8-bit, 16-bit and 32-bit
libraries that are enabled. If you want to run just one set of tests, call
RunTest with either the -8, -16 or -32 option.
-RunTest uses a file called testtry to hold the main output from pcretest.
-Other files whose names begin with "test" are used as working files in some
-tests. To run pcretest on just one or more specific test files, give their
-numbers as arguments to RunTest, for example:
+If valgrind is installed, you can run the tests under it by putting "valgrind"
+on the RunTest command line. To run pcretest on just one or more specific test
+files, give their numbers as arguments to RunTest, for example:
RunTest 2 7 11
+You can also specify ranges of tests such as 3-6 or 3- (meaning 3 to the
+end), or a number preceded by ~ to exclude a test. For example:
+
+ Runtest 3-15 ~10
+
+This runs tests 3 to 15, excluding test 10, and just ~13 runs all the tests
+except test 13. Whatever order the arguments are in, the tests are always run
+in numerical order.
+
You can also call RunTest with the single argument "list" to cause it to output
a list of tests.
@@ -704,21 +756,24 @@ test is run only when JIT support is not available. They test some JIT-specific
features such as information output from pcretest about JIT compilation.
The fourteenth, fifteenth, and sixteenth tests are run only in 8-bit mode, and
-the seventeenth, eighteenth, and nineteenth tests are run only in 16/32-bit mode.
-These are tests that generate different output in the two modes. They are for
-general cases, UTF-8/16/32 support, and Unicode property support, respectively.
+the seventeenth, eighteenth, and nineteenth tests are run only in 16/32-bit
+mode. These are tests that generate different output in the two modes. They are
+for general cases, UTF-8/16/32 support, and Unicode property support,
+respectively.
The twentieth test is run only in 16/32-bit mode. It tests some specific
16/32-bit features of the DFA matching engine.
-The twenty-first and twenty-second tests are run only in 16/32-bit mode, when the
-link size is set to 2 for the 16-bit library. They test reloading pre-compiled patterns.
+The twenty-first and twenty-second tests are run only in 16/32-bit mode, when
+the link size is set to 2 for the 16-bit library. They test reloading
+pre-compiled patterns.
+
+The twenty-third and twenty-fourth tests are run only in 16-bit mode. They are
+for general cases, and UTF-16 support, respectively.
-The twenty-third and twenty-fourth tests are run only in 16-bit mode. They are for
-general cases, and UTF-16 support, respectively.
+The twenty-fifth and twenty-sixth tests are run only in 32-bit mode. They are
+for general cases, and UTF-32 support, respectively.
-The twenty-fifth and twenty-sixth tests are run only in 32-bit mode. They are for
-general cases, and UTF-32 support, respectively.
Character tables
----------------
@@ -784,11 +839,11 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx.
(A) Source files of the PCRE library functions and their headers:
dftables.c auxiliary program for building pcre_chartables.c
- when --enable-rebuild-chartables is specified
+ when --enable-rebuild-chartables is specified
pcre_chartables.c.dist a default set of character tables that assume ASCII
- coding; used, unless --enable-rebuild-chartables is
- specified, by copying to pcre[16]_chartables.c
+ coding; used, unless --enable-rebuild-chartables is
+ specified, by copying to pcre[16]_chartables.c
pcreposix.c )
pcre[16|32]_byte_order.c )
@@ -932,4 +987,4 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx.
Philip Hazel
Email local part: ph10
Email domain: cam.ac.uk
-Last updated: 27 October 2012
+Last updated: 05 November 2013
diff --git a/ext/pcre/pcrelib/config.h b/ext/pcre/pcrelib/config.h
index bd18f535a7..a3b1b5dd38 100644
--- a/ext/pcre/pcrelib/config.h
+++ b/ext/pcre/pcrelib/config.h
@@ -302,6 +302,8 @@ them both to 0; an emulation function will be used. */
*/
/* #undef NO_RECURSE */
+#define PARENS_NEST_LIMIT 250
+
/* Name of package */
#define PACKAGE "pcre"
@@ -430,7 +432,7 @@ them both to 0; an emulation function will be used. */
/* Version number of package */
#ifndef VERSION
-#define VERSION "8.32"
+#define VERSION "8.34"
#endif
/* Define to empty if `const' does not conform to ANSI C. */
diff --git a/ext/pcre/pcrelib/doc/pcre.txt b/ext/pcre/pcrelib/doc/pcre.txt
index 2a2a82c7f1..9d69515c3b 100644
--- a/ext/pcre/pcrelib/doc/pcre.txt
+++ b/ext/pcre/pcrelib/doc/pcre.txt
@@ -8,13 +8,13 @@ pcretest commands.
-----------------------------------------------------------------------------
-PCRE(3) PCRE(3)
+PCRE(3) Library Functions Manual PCRE(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
INTRODUCTION
The PCRE library is a set of functions that implement regular expres-
@@ -33,110 +33,113 @@ INTRODUCTION
possible was done by Zoltan Herczeg.
Starting with release 8.32 it is possible to compile a third separate
- PCRE library, which supports 32-bit character strings (including UTF-32
- strings). The build process allows any set of the 8-, 16- and 32-bit
- libraries. The work to make this possible was done by Christian Persch.
-
- The three libraries contain identical sets of functions, except that
- the names in the 16-bit library start with pcre16_ instead of pcre_,
- and the names in the 32-bit library start with pcre32_ instead of
- pcre_. To avoid over-complication and reduce the documentation mainte-
+ PCRE library that supports 32-bit character strings (including UTF-32
+ strings). The build process allows any combination of the 8-, 16- and
+ 32-bit libraries. The work to make this possible was done by Christian
+ Persch.
+
+ The three libraries contain identical sets of functions, except that
+ the names in the 16-bit library start with pcre16_ instead of pcre_,
+ and the names in the 32-bit library start with pcre32_ instead of
+ pcre_. To avoid over-complication and reduce the documentation mainte-
nance load, most of the documentation describes the 8-bit library, with
- the differences for the 16-bit and 32-bit libraries described sepa-
- rately in the pcre16 and pcre32 pages. References to functions or
- structures of the form pcre[16|32]_xxx should be read as meaning
- "pcre_xxx when using the 8-bit library, pcre16_xxx when using the
+ the differences for the 16-bit and 32-bit libraries described sepa-
+ rately in the pcre16 and pcre32 pages. References to functions or
+ structures of the form pcre[16|32]_xxx should be read as meaning
+ "pcre_xxx when using the 8-bit library, pcre16_xxx when using the
16-bit library, or pcre32_xxx when using the 32-bit library".
- The current implementation of PCRE corresponds approximately with Perl
- 5.12, including support for UTF-8/16/32 encoded strings and Unicode
- general category properties. However, UTF-8/16/32 and Unicode support
+ The current implementation of PCRE corresponds approximately with Perl
+ 5.12, including support for UTF-8/16/32 encoded strings and Unicode
+ general category properties. However, UTF-8/16/32 and Unicode support
has to be explicitly enabled; it is not the default. The Unicode tables
- correspond to Unicode release 6.2.0.
+ correspond to Unicode release 6.3.0.
- In addition to the Perl-compatible matching function, PCRE contains an
- alternative function that matches the same compiled patterns in a dif-
+ In addition to the Perl-compatible matching function, PCRE contains an
+ alternative function that matches the same compiled patterns in a dif-
ferent way. In certain circumstances, the alternative function has some
- advantages. For a discussion of the two matching algorithms, see the
+ advantages. For a discussion of the two matching algorithms, see the
pcrematching page.
- 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 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,
+ 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 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-AUTOTOOLS_BUILD files in the source distribution.
- 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_" or "_pcre32_", 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
+ 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_" or "_pcre32_", 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.
SECURITY CONSIDERATIONS
- If you are using PCRE in a non-UTF application that permits users to
- supply arbitrary patterns for compilation, you should be aware of a
+ If you are using PCRE in a non-UTF application that permits users to
+ supply arbitrary patterns for compilation, you should be aware of a
feature that allows users to turn on UTF support from within a pattern,
- provided that PCRE was built with UTF support. For example, an 8-bit
- pattern that begins with "(*UTF8)" or "(*UTF)" turns on UTF-8 mode,
- which interprets patterns and subjects as strings of UTF-8 characters
- instead of individual 8-bit characters. This causes both the pattern
+ provided that PCRE was built with UTF support. For example, an 8-bit
+ pattern that begins with "(*UTF8)" or "(*UTF)" turns on UTF-8 mode,
+ which interprets patterns and subjects as strings of UTF-8 characters
+ instead of individual 8-bit characters. This causes both the pattern
and any data against which it is matched to be checked for UTF-8 valid-
- ity. If the data string is very long, such a check might use suffi-
- ciently many resources as to cause your application to lose perfor-
+ ity. If the data string is very long, such a check might use suffi-
+ ciently many resources as to cause your application to lose perfor-
mance.
- The best way of guarding against this possibility is to use the
- pcre_fullinfo() function to check the compiled pattern's options for
- UTF.
+ One way of guarding against this possibility is to use the
+ pcre_fullinfo() function to check the compiled pattern's options for
+ UTF. Alternatively, from release 8.33, you can set the PCRE_NEVER_UTF
+ option at compile time. This causes an compile time error if a pattern
+ contains a UTF-setting sequence.
- If your application is one that supports UTF, be aware that validity
- checking can take time. If the same data string is to be matched many
+ If your application is one that supports UTF, be aware that validity
+ checking can take time. If the same data string is to be matched many
times, you can use the PCRE_NO_UTF[8|16|32]_CHECK option for the second
and subsequent matches to save redundant checks.
- Another way that performance can be hit is by running a pattern that
- has a very large search tree against a string that will never match.
- Nested unlimited repeats in a pattern are a common example. PCRE pro-
+ Another way that performance can be hit is by running a pattern that
+ has a very large search tree against a string that will never match.
+ Nested unlimited repeats in a pattern are a common example. PCRE pro-
vides some protection against this: see the PCRE_EXTRA_MATCH_LIMIT fea-
ture in the pcreapi page.
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
+ pcre-config show PCRE installation configuration information
pcre16 details of the 16-bit library
pcre32 details of the 32-bit library
- pcre-config show PCRE installation configuration information
pcreapi details of PCRE's native C API
- pcrebuild options for building PCRE
+ pcrebuild building PCRE
pcrecallout details of the callout feature
pcrecompat discussion of Perl compatibility
pcrecpp details of the C++ wrapper for the 8-bit library
@@ -157,7 +160,7 @@ USER DOCUMENTATION
pcretest description of the pcretest testing command
pcreunicode discussion of Unicode and UTF-8/16/32 support
- In addition, in the "man" and HTML formats, there is a short page for
+ In addition, in the "man" and HTML formats, there is a short page for
each C library function, listing its arguments and results.
@@ -167,19 +170,20 @@ AUTHOR
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,
+ 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: 11 November 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 13 May 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCRE(3) PCRE(3)
+PCRE(3) Library Functions Manual PCRE(3)
+
NAME
@@ -389,8 +393,10 @@ STRUCTURE TYPES
SUBJECT STRING OFFSETS
- The offsets within subject strings that are returned by the matching
- functions are in 16-bit units rather than bytes.
+ The lengths and starting offsets of subject strings must be specified
+ in 16-bit data units, and the offsets within subject strings that are
+ returned by the matching functions are in also 16-bit units rather than
+ bytes.
NAMED SUBPATTERNS
@@ -503,12 +509,13 @@ AUTHOR
REVISION
- Last updated: 08 November 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 12 May 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCRE(3) PCRE(3)
+PCRE(3) Library Functions Manual PCRE(3)
+
NAME
@@ -525,7 +532,6 @@ PCRE 32-BIT API BASIC FUNCTIONS
pcre32 *pcre32_compile2(PCRE_SPTR32 pattern, int options,
int *errorcodeptr,
- const char **errptr, int *erroffset,
const unsigned char *tableptr);
pcre32_extra *pcre32_study(const pcre32 *code, int options,
@@ -718,8 +724,10 @@ STRUCTURE TYPES
SUBJECT STRING OFFSETS
- The offsets within subject strings that are returned by the matching
- functions are in 32-bit units rather than bytes.
+ The lengths and starting offsets of subject strings must be specified
+ in 32-bit data units, and the offsets within subject strings that are
+ returned by the matching functions are in also 32-bit units rather than
+ bytes.
NAMED SUBPATTERNS
@@ -829,33 +837,46 @@ AUTHOR
REVISION
- Last updated: 08 November 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 12 May 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCREBUILD(3) PCREBUILD(3)
+PCREBUILD(3) Library Functions Manual PCREBUILD(3)
+
NAME
PCRE - Perl-compatible regular expressions
+BUILDING PCRE
+
+ PCRE is distributed with a configure script that can be used to build
+ the library in Unix-like environments using the applications known as
+ Autotools. Also in the distribution are files to support building
+ using CMake instead of configure. The text file README contains general
+ information about building with Autotools (some of which is repeated
+ below), and also has some comments about building on various operating
+ systems. There is a lot more information about building PCRE without
+ using Autotools (including information about using CMake and building
+ "by hand") in the text file called NON-AUTOTOOLS-BUILD. You should
+ consult this file as well as the README file if you are building in a
+ non-Unix-like environment.
+
PCRE BUILD-TIME OPTIONS
- This document describes the optional features of PCRE that can be
- selected when the library is compiled. It assumes use of the configure
- script, where the optional features are selected or deselected by pro-
- viding options to configure before running the make command. However,
- the same options can be selected in both Unix-like and non-Unix-like
- environments using the GUI facility of cmake-gui if you are using CMake
- instead of configure to build PCRE.
+ The rest of this document describes the optional features of PCRE that
+ can be selected when the library is compiled. It assumes use of the
+ configure script, where the optional features are selected or dese-
+ lected by providing options to configure before running the make com-
+ mand. However, the same options can be selected in both Unix-like and
+ non-Unix-like environments using the GUI facility of cmake-gui if you
+ are using CMake instead of configure to build PCRE.
- There is a lot more information about building PCRE without using con-
- figure (including information about using CMake or building "by hand")
- in the file called NON-AUTOTOOLS-BUILD, which is part of the PCRE dis-
- tribution. You should consult this file as well as the README file if
- you are building in a non-Unix-like environment.
+ If you are not using Autotools or CMake, option selection can be done
+ by editing the config.h file, or by passing parameter settings to the
+ compiler, as described in NON-AUTOTOOLS-BUILD.
The complete list of options for configure (which includes the standard
ones such as the selection of the installation directory) can be
@@ -882,10 +903,10 @@ BUILDING 8-BIT, 16-BIT AND 32-BIT LIBRARIES
--enable-pcre16
- to the configure command. You can also build a separate library, called
- libpcre32, in which strings are contained in vectors of 32-bit data
- units and interpreted either as single-unit characters or UTF-32
- strings, by adding
+ to the configure command. You can also build yet another separate
+ library, called libpcre32, in which strings are contained in vectors of
+ 32-bit data units and interpreted either as single-unit characters or
+ UTF-32 strings, by adding
--enable-pcre32
@@ -901,9 +922,9 @@ BUILDING 8-BIT, 16-BIT AND 32-BIT LIBRARIES
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
+ The Autotools PCRE building process uses libtool to build both shared
+ and static libraries by default. You can suppress one of these by
+ adding one of
--disable-shared
--disable-static
@@ -1319,18 +1340,18 @@ AUTHOR
REVISION
- Last updated: 30 October 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 12 May 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCREMATCHING(3) PCREMATCHING(3)
+PCREMATCHING(3) Library Functions Manual PCREMATCHING(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
PCRE MATCHING ALGORITHMS
This document describes the two different algorithms that are available
@@ -1436,72 +1457,81 @@ THE ALTERNATIVE MATCHING ALGORITHM
at the fifth character of the subject. The algorithm does not automati-
cally move on to find matches that start at later positions.
+ PCRE's "auto-possessification" optimization usually applies to charac-
+ ter repeats at the end of a pattern (as well as internally). For exam-
+ ple, the pattern "a\d+" is compiled as if it were "a\d++" because there
+ is no point even considering the possibility of backtracking into the
+ repeated digits. For DFA matching, this means that only one possible
+ match is found. If you really do want multiple matches in such cases,
+ either use an ungreedy repeat ("a\d+?") or set the PCRE_NO_AUTO_POSSESS
+ option when compiling.
+
There are a number of features of PCRE regular expressions that are not
supported by the alternative matching algorithm. They are as follows:
- 1. Because the algorithm finds all possible matches, the greedy or
- ungreedy nature of repetition quantifiers is not relevant. Greedy and
+ 1. Because the algorithm finds all possible matches, the greedy or
+ ungreedy nature of repetition quantifiers is not relevant. Greedy and
ungreedy quantifiers are treated in exactly the same way. However, pos-
- sessive quantifiers can make a difference when what follows could also
+ sessive quantifiers can make a difference when what follows could also
match what is quantified, for example in a pattern like this:
^a++\w!
- This pattern matches "aaab!" but not "aaa!", which would be matched by
- a non-possessive quantifier. Similarly, if an atomic group is present,
- it is matched as if it were a standalone pattern at the current point,
- and the longest match is then "locked in" for the rest of the overall
+ This pattern matches "aaab!" but not "aaa!", which would be matched by
+ a non-possessive quantifier. Similarly, if an atomic group is present,
+ it is matched as if it were a standalone pattern at the current point,
+ and the longest match is then "locked in" for the rest of the overall
pattern.
2. When dealing with multiple paths through the tree simultaneously, it
- is not straightforward to keep track of captured substrings for the
- different matching possibilities, and PCRE's implementation of this
+ is not straightforward to keep track of captured substrings for the
+ different matching possibilities, and PCRE's implementation of this
algorithm does not attempt to do this. This means that no captured sub-
strings are available.
- 3. Because no substrings are captured, back references within the pat-
+ 3. Because no substrings are captured, back references within the pat-
tern are not supported, and cause errors if encountered.
- 4. For the same reason, conditional expressions that use a backrefer-
- ence as the condition or test for a specific group recursion are not
+ 4. For the same reason, conditional expressions that use a backrefer-
+ ence as the condition or test for a specific group recursion are not
supported.
- 5. Because many paths through the tree may be active, the \K escape
+ 5. Because many paths through the tree may be active, the \K escape
sequence, which resets the start of the match when encountered (but may
- be on some paths and not on others), is not supported. It causes an
+ be on some paths and not on others), is not supported. It causes an
error if encountered.
- 6. Callouts are supported, but the value of the capture_top field is
+ 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) always
- matches a single data unit, even in UTF-8, UTF-16 or UTF-32 modes, is
- not supported in these modes, because the alternative algorithm moves
+ 7. The \C escape sequence, which (in the standard algorithm) always
+ matches a single data unit, even in UTF-8, UTF-16 or UTF-32 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 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
+ 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
+ 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-
+ 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.
@@ -1509,8 +1539,8 @@ 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.
@@ -1528,12 +1558,13 @@ AUTHOR
REVISION
- Last updated: 08 January 2012
+ Last updated: 12 November 2013
Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
-PCREAPI(3) PCREAPI(3)
+PCREAPI(3) Library Functions Manual PCREAPI(3)
+
NAME
@@ -1663,68 +1694,67 @@ PCRE 8-BIT, 16-BIT, AND 32-BIT LIBRARIES
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, or 32-bit data quantities and UTF-32 when using the 32-bit
- library, unless specified otherwise. More details of the specific dif-
- ferences for the 16-bit and 32-bit libraries are given in the pcre16
- and pcre32 pages.
+ ences to 16-bit data units and UTF-16 when using the 16-bit library, or
+ 32-bit data units and UTF-32 when using the 32-bit library, unless
+ specified otherwise. More details of the specific differences for the
+ 16-bit and 32-bit libraries are given in the pcre16 and pcre32 pages.
PCRE API OVERVIEW
PCRE has its own native API, which is described in this document. There
- 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
+ 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
+ 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
+ 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
+ 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
+ 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.
- From release 8.32 there is also a direct interface for JIT execution,
- which gives improved performance. The JIT-specific functions are dis-
+ From release 8.32 there is also a direct interface for JIT execution,
+ which gives improved performance. The JIT-specific functions are dis-
cussed 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:
@@ -1739,105 +1769,105 @@ PCRE API OVERVIEW
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. The function pcre_version() returns a pointer to a
+ 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
+ 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
+ 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, 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-
+ 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.
@@ -1845,45 +1875,45 @@ CHECKING BUILD-TIME OPTIONS
int pcre_config(int what, void *where);
- The function pcre_config() makes it possible for a PCRE client to dis-
+ The function pcre_config() makes it possible for a PCRE client to dis-
cover which optional features have been compiled into the PCRE library.
- The pcrebuild documentation has more details about these optional fea-
+ The pcrebuild documentation has more details about these optional fea-
tures.
- The first argument for pcre_config() is an integer, specifying which
+ 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 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
+ 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. This value should normally be given
+ The output is an integer that is set to one if UTF-8 support is avail-
+ able; otherwise it is set to zero. This value should normally be given
to the 8-bit version of this function, pcre_config(). If it is given to
- the 16-bit or 32-bit version of this function, the result is
+ the 16-bit or 32-bit version of this function, 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
+ 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 or 32-bit version of this function, the result is
+ to the 8-bit or 32-bit version of this function, the result is
PCRE_ERROR_BADOPTION.
PCRE_CONFIG_UTF32
The output is an integer that is set to one if UTF-32 support is avail-
- able; otherwise it is set to zero. This value should normally be given
+ able; otherwise it is set to zero. This value should normally be given
to the 32-bit version of this function, pcre32_config(). If it is given
- to the 8-bit or 16-bit version of this function, the result is
+ to the 8-bit or 16-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
+ 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
@@ -1893,49 +1923,56 @@ CHECKING BUILD-TIME OPTIONS
PCRE_CONFIG_JITTARGET
- The output is a pointer to a zero-terminated "const char *" string. If
+ 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
+ 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 values that are
+ The output is an integer whose value specifies the default character
+ sequence that is recognized as meaning "newline". The values that are
supported in ASCII/Unicode environments are: 10 for LF, 13 for CR, 3338
- for CRLF, -2 for ANYCRLF, and -1 for ANY. In EBCDIC environments, CR,
- ANYCRLF, and ANY yield the same values. However, the value for LF is
- normally 21, though some EBCDIC environments use 37. The corresponding
- values for CRLF are 3349 and 3365. The default should normally corre-
+ for CRLF, -2 for ANYCRLF, and -1 for ANY. In EBCDIC environments, CR,
+ ANYCRLF, and ANY yield the same values. However, the value for LF is
+ normally 21, though some EBCDIC environments use 37. The corresponding
+ values for CRLF are 3349 and 3365. 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
+ 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. For the 32-bit
+ is either 2 or 4 and is still a number of bytes. For the 32-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
+ 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_PARENS_LIMIT
+
+ The output is a long integer that gives the maximum depth of nesting of
+ parentheses (of any kind) in a pattern. This limit is imposed to cap
+ the amount of system stack used when a pattern is compiled. It is spec-
+ ified when PCRE is built; the default is 250.
+
PCRE_CONFIG_MATCH_LIMIT
The output is a long integer that gives the default limit for the num-
@@ -2008,15 +2045,17 @@ COMPILING A PATTERN
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. Normally, the offset from the start of the pattern to
- the byte that was being processed when the error was discovered is
+ the data unit 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.
+ or UTF-16 string, the offset is that of the first data unit 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 sometimes point into the middle of a UTF-8 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 data units, not characters, even in a UTF
+ mode. It may sometimes point into the middle of a UTF-8 or UTF-16 char-
+ acter.
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
@@ -2027,9 +2066,9 @@ COMPILING A PATTERN
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.
+ compiled pattern, and used again by pcre_exec() and pcre_dfa_exec()
+ when the pattern is matched. For more discussion, see the section on
+ locale support below.
This code fragment shows a typical straightforward call to pcre_com-
pile():
@@ -2113,13 +2152,23 @@ COMPILING A PATTERN
PCRE_EXTENDED
- 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-
- ting.
+ If this bit is set, most white space characters in the pattern are
+ totally ignored except when escaped or inside a character class. How-
+ ever, white space is not allowed within sequences such as (?> that
+ introduce various parenthesized subpatterns, nor within a numerical
+ quantifier such as {1,3}. However, ignorable white space is permitted
+ between an item and a following quantifier and between a quantifier and
+ a following + that indicates possessiveness.
+
+ White space did not used to include the VT character (code 11), because
+ Perl did not treat this character as white space. However, Perl changed
+ at release 5.18, so PCRE followed at release 8.34, and VT is now
+ treated as white space.
+
+ PCRE_EXTENDED also causes characters between an unescaped # outside a
+ character class and the next newline, inclusive, to be ignored.
+ PCRE_EXTENDED 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
@@ -2186,21 +2235,33 @@ COMPILING A PATTERN
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
- 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
+ By default, for the purposes of matching "start of line" and "end of
+ line", 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, and the "end
+ of line" metacharacter ($) matches only at the end of the string, or
+ before a terminating newline (except when PCRE_DOLLAR_ENDONLY is set).
+ Note, however, that unless PCRE_DOTALL is set, the "any character"
+ metacharacter (.) does not match at a newline. This behaviour (for ^,
+ $, and dot) 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
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_NEVER_UTF
+
+ This option locks out interpretation of the pattern as UTF-8 (or UTF-16
+ or UTF-32 in the 16-bit and 32-bit libraries). In particular, it pre-
+ vents the creator of the pattern from switching to UTF interpretation
+ by starting the pattern with (*UTF). This may be useful in applications
+ that process patterns from external sources. The combination of
+ PCRE_UTF8 and PCRE_NEVER_UTF also causes an error.
+
PCRE_NEWLINE_CR
PCRE_NEWLINE_LF
PCRE_NEWLINE_CRLF
@@ -2255,63 +2316,74 @@ COMPILING A PATTERN
be used for capturing (and they acquire numbers in the usual way).
There is no equivalent of this option in Perl.
- NO_START_OPTIMIZE
+ PCRE_NO_AUTO_POSSESS
+
+ If this option is set, it disables "auto-possessification". This is an
+ optimization that, for example, turns a+b into a++b in order to avoid
+ backtracks into a+ that can never be successful. However, if callouts
+ are in use, auto-possessification means that some of them are never
+ taken. You can set this option if you want the matching functions to do
+ a full unoptimized search and run all the callouts, but it is mainly
+ provided for testing purposes.
+
+ 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.
+ ing time. This is necessary if you want to use JIT execution, because
+ the JIT compiler needs to know whether or not this option is set. 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
+ 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
+ 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 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
+ 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 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 only. If the same string is being matched
- many times, the option can be safely set for the second and subsequent
+ may cause your program to crash or loop. Note that this option can also
+ be passed to pcre_exec() and pcre_dfa_exec(), to suppress the validity
+ checking of subject strings only. If the same string is being matched
+ many times, the option can be safely set for the second and subsequent
matchings to improve performance.
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. Note that error messages are always 8-bit
- ASCII strings, even in 16-bit or 32-bit mode. As PCRE has developed,
- some error codes have fallen out of use. To avoid confusion, they have
+ 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. Note that error messages are always 8-bit
+ ASCII strings, even in 16-bit or 32-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
@@ -2348,7 +2420,7 @@ COMPILATION ERROR CODES
31 POSIX collating elements are not supported
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
+ 34 character value in \x{} or \o{} is too large
35 invalid condition (?(0)
36 \C not allowed in lookbehind assertion
37 PCRE does not support \L, \l, \N{name}, \U, or \u
@@ -2376,7 +2448,7 @@ COMPILATION ERROR CODES
name/number or by a plain number
58 a numbered reference must not be zero
59 an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)
- 60 (*VERB) not recognized
+ 60 (*VERB) not recognized or malformed
61 number is too big
62 subpattern name expected
63 digit expected after (?+
@@ -2396,74 +2468,80 @@ COMPILATION ERROR CODES
75 name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
76 character value in \u.... sequence is too large
77 invalid UTF-32 string (specifically UTF-32)
-
- The numbers 32 and 10000 in errors 48 and 49 are defaults; different
+ 78 setting UTF is disabled by the application
+ 79 non-hex character in \x{} (closing brace missing?)
+ 80 non-octal character in \o{} (closing brace missing?)
+ 81 missing opening brace after \o
+ 82 parentheses are too deeply nested
+ 83 invalid range in character class
+
+ 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
- pcre_extra *pcre_study(const pcre *code, int options
+ pcre_extra *pcre_study(const pcre *code, int options,
const char **errptr);
- If a compiled pattern is going to be used several times, it is worth
+ If a compiled pattern is going to be used several times, it is worth
spending more time analyzing it in order to speed up the time taken for
- matching. The function pcre_study() takes a pointer to a compiled pat-
+ matching. The function pcre_study() takes a pointer to a compiled pat-
tern as its first argument. If studying the pattern produces additional
- information that will help speed up matching, pcre_study() returns a
- pointer to a pcre_extra block, in which the study_data field points to
+ information that will help speed up matching, pcre_study() returns a
+ pointer to a pcre_extra block, in which the study_data field points to
the results of the study.
The returned value from pcre_study() can be passed directly to
- pcre_exec() or pcre_dfa_exec(). However, a pcre_extra block also con-
- tains other fields that can be set by the caller before the block is
+ pcre_exec() or pcre_dfa_exec(). However, a pcre_extra block also con-
+ tains other fields that can be set by the caller before the block is
passed; these are described below in the section on matching a pattern.
- If studying the pattern does not produce any useful information,
- pcre_study() returns NULL by default. In that circumstance, if the
+ If studying the pattern does not produce any useful information,
+ pcre_study() returns NULL by default. In that circumstance, if the
calling program wants to pass any of the other fields to pcre_exec() or
- pcre_dfa_exec(), it must set up its own pcre_extra block. However, if
- pcre_study() is called with the PCRE_STUDY_EXTRA_NEEDED option, it
+ pcre_dfa_exec(), it must set up its own pcre_extra block. However, if
+ pcre_study() is called with the PCRE_STUDY_EXTRA_NEEDED option, it
returns a pcre_extra block even if studying did not find any additional
- information. It may still return NULL, however, if an error occurs in
+ information. It may still return NULL, however, if an error occurs in
pcre_study().
- The second argument of pcre_study() contains option bits. There are
+ The second argument of pcre_study() contains option bits. There are
three further options in addition to PCRE_STUDY_EXTRA_NEEDED:
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
+ 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
undefined 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
+ 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-
+ 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
- points to is set to NULL. Otherwise it is set to point to a textual
+ 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
+ points to is set to NULL. Otherwise it is set 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. You should test the error pointer for NULL
+ 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.
- When you are finished with a pattern, you can free the memory used for
+ 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
+ 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
+ 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;
@@ -2483,41 +2561,50 @@ STUDYING A PATTERN
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 mean that there are any strings of that length that match, but
- it does guarantee that no shorter strings match. The value is used to
+ it does guarantee that no shorter strings match. The value is used to
avoid wasting time by trying to match strings that are shorter than the
- lower bound. You can find out the value in a calling program via the
+ lower bound. You can find out the value in a calling program via the
pcre_fullinfo() function.
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
+ 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. (In 16-bit mode, the bitmap is used for 16-bit
- values less than 256. In 32-bit mode, the bitmap is used for 32-bit
+ values less than 256. In 32-bit mode, the bitmap is used for 32-bit
values less than 256.)
- 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.
+ 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.
+ 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.
+
+ PCRE_NO_START_OPTIMIZE can be specified at either compile time or exe-
+ cution time. However, if PCRE_NO_START_OPTIMIZE is passed to
+ pcre_exec(), (that is, after any JIT compilation has happened) JIT exe-
+ cution is disabled. For JIT execution to work with PCRE_NO_START_OPTI-
+ MIZE, the option must be set at compile time.
+
+ There is a longer 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
- 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 charac-
- 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 handles caseless matching, and determines whether characters are
+ letters, digits, or whatever, by reference to a set of tables, indexed
+ by character code point. When running in UTF-8 mode, or in the 16- or
+ 32-bit libraries, this applies only to characters with code points less
+ than 256. By default, higher-valued code points never match escapes
+ such as \w or \d. However, if PCRE is built with Unicode property sup-
+ port, all characters can be tested with \p and \P, or, alternatively,
+ the PCRE_UCP option can be set when a pattern is compiled; this causes
+ \w and friends to use Unicode property support instead of the built-in
+ tables.
+
+ The use of locales with Unicode is discouraged. If you are handling
+ characters with code points greater than 128, you should either use
+ Unicode support, 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
@@ -2533,10 +2620,10 @@ LOCALE SUPPORT
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:
+ passed to pcre_compile() 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 let-
+ ters), the following code could be used:
setlocale(LC_CTYPE, "fr_FR");
tables = pcre_maketables();
@@ -2552,15 +2639,19 @@ LOCALE SUPPORT
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()
- and normally also by pcre_exec(). Thus, by default, for any single pat-
+ and also by pcre_exec() and pcre_dfa_exec(). Thus, for any single pat-
tern, compilation, studying and matching all happen in the same locale,
- but different patterns can be compiled in different locales.
+ but different patterns can be processed 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
- 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.
+ the internal tables) to pcre_exec() or pcre_dfa_exec() (see the discus-
+ sion below in the section on matching a pattern). This facility is pro-
+ vided for use with pre-compiled patterns that have been saved and
+ reloaded. Character tables are not saved with patterns, so if a non-
+ standard table was used at compile time, it must be provided again when
+ the reloaded pattern is matched. Attempting to use this facility to
+ match a pattern in a different locale from the one in which it was com-
+ piled is likely to lead to anomalous (usually incorrect) results.
INFORMATION ABOUT A PATTERN
@@ -2585,6 +2676,7 @@ INFORMATION ABOUT A PATTERN
PCRE_ERROR_BADENDIANNESS the pattern was compiled with different
endianness
PCRE_ERROR_BADOPTION the value of what was invalid
+ PCRE_ERROR_UNSET the requested field is not set
The "magic number" is placed at the start of each compiled pattern as
an simple check against passing an arbitrary memory pointer. The endi-
@@ -2700,23 +2792,41 @@ INFORMATION ABOUT A PATTERN
/^a\dz\d/ the returned value is -1.
Since for the 32-bit library using the non-UTF-32 mode, this function
- is unable to return the full 32-bit range of the character, this value
- is deprecated; instead the PCRE_INFO_REQUIREDCHARFLAGS and
+ is unable to return the full 32-bit range of characters, this value is
+ deprecated; instead the PCRE_INFO_REQUIREDCHARFLAGS and
PCRE_INFO_REQUIREDCHAR values should be used.
+ PCRE_INFO_MATCH_EMPTY
+
+ Return 1 if the pattern can match an empty string, otherwise 0. The
+ fourth argument should point to an int variable.
+
+ PCRE_INFO_MATCHLIMIT
+
+ If the pattern set a match limit by including an item of the form
+ (*LIMIT_MATCH=nnnn) at the start, the value is returned. The fourth
+ argument should point to an unsigned 32-bit integer. If no such value
+ has been set, the call to pcre_fullinfo() returns the error
+ PCRE_ERROR_UNSET.
+
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.
+ Return the number of characters (NB not data units) in the longest
+ lookbehind assertion in the pattern. This information is useful when
+ doing multi-segment matching using the partial matching facilities.
+ Note that the simple assertions \b and \B require a one-character look-
+ behind. \A also registers a one-character lookbehind, though it does
+ not actually inspect the previous character. This is to ensure that at
+ least one character from the old segment is retained when a new segment
+ is processed. Otherwise, if there are no lookbehinds in the pattern, \A
+ might match incorrectly at the start of a new segment.
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, which in UTF-8 mode
- may be different from the number of bytes. The fourth argument should
+ value is -1. The value is a number of characters, which in UTF mode may
+ be different from the number of data units. 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
@@ -2744,30 +2854,31 @@ INFORMATION ABOUT A PATTERN
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. In the 32-bit library, the
+ which contains the parenthesis number. In the 32-bit library, the
pointer points to 32-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
- the section on duplicate subpattern numbers in the pcrepattern page.
- Duplicate names for subpatterns with different numbers are permitted
- only if PCRE_DUPNAMES is set. In all cases of duplicate names, they
- appear in the table in the order in which they were found in the pat-
- tern. In the absence of (?| this is the order of increasing number;
- when (?| is used this is not necessarily the case because later subpat-
- terns may have lower numbers.
-
- As a simple example of the name/number table, consider the following
+ The names are in alphabetical order. If (?| is used to create multiple
+ groups with the same number, as described in the section on duplicate
+ subpattern numbers in the pcrepattern page, the groups may be given the
+ same name, but there is only one entry in the table. Different names
+ for groups of the same number are not permitted. Duplicate names for
+ subpatterns with different numbers are permitted, but only if PCRE_DUP-
+ NAMES is set. They appear in the table in the order in which they were
+ found in the pattern. In the absence of (?| this is the order of
+ increasing number; when (?| is used this is not necessarily the case
+ because later subpatterns may have lower numbers.
+
+ As a simple example of the name/number table, consider the following
pattern after compilation by the 8-bit library (assume PCRE_EXTENDED is
set, so white space - including newlines - is ignored):
(?<date> (?<year>(\d\d)?\d\d) -
(?<month>\d\d) - (?<day>\d\d) )
- There are four named subpatterns, so the table has four entries, and
- each entry in the table is eight bytes long. The table is as follows,
+ There are four named subpatterns, so the table has four entries, and
+ each entry in the table is eight bytes long. The table is as follows,
with non-printing bytes shows in hexadecimal, and undefined bytes shown
as ??:
@@ -2776,31 +2887,31 @@ INFORMATION ABOUT A PATTERN
00 04 m o n t h 00
00 02 y e a r 00 ??
- When writing code to extract data from named subpatterns using the
- name-to-number map, remember that the length of the entries is likely
+ When writing code to extract data from named subpatterns using the
+ name-to-number map, remember that the length of the entries is likely
to be different for each compiled pattern.
PCRE_INFO_OKPARTIAL
- Return 1 if the pattern can be used for partial matching with
- pcre_exec(), otherwise 0. The fourth argument should point to an int
- variable. From release 8.00, this always returns 1, because the
- restrictions that previously applied to partial matching have been
- lifted. The pcrepartial documentation gives details of partial match-
+ Return 1 if the pattern can be used for partial matching with
+ pcre_exec(), otherwise 0. The fourth argument should point to an int
+ variable. From release 8.00, this always returns 1, because the
+ restrictions that previously applied to partial matching have been
+ lifted. The pcrepartial documentation gives details of partial match-
ing.
PCRE_INFO_OPTIONS
- Return a copy of the options with which the pattern was compiled. The
- fourth argument should point to an unsigned long int variable. These
+ Return a copy of the options with which the pattern was compiled. The
+ fourth argument should point to an unsigned long int variable. These
option bits are those specified in the call to pcre_compile(), modified
by any top-level option settings at the start of the pattern itself. In
- other words, they are the options that will be in force when matching
- starts. For example, if the pattern /(?im)abc(?-i)d/ is compiled with
- the PCRE_EXTENDED option, the result is PCRE_CASELESS, PCRE_MULTILINE,
+ other words, they are the options that will be in force when matching
+ starts. For example, if the pattern /(?im)abc(?-i)d/ is compiled with
+ the PCRE_EXTENDED option, the result is PCRE_CASELESS, PCRE_MULTILINE,
and PCRE_EXTENDED.
- A pattern is automatically anchored by PCRE if all of its top-level
+ A pattern is automatically anchored by PCRE if all of its top-level
alternatives begin with one of the following:
^ unless PCRE_MULTILINE is set
@@ -2812,42 +2923,50 @@ INFORMATION ABOUT A PATTERN
For such patterns, the PCRE_ANCHORED bit is set in the options returned
by pcre_fullinfo().
+ PCRE_INFO_RECURSIONLIMIT
+
+ If the pattern set a recursion limit by including an item of the form
+ (*LIMIT_RECURSION=nnnn) at the start, the value is returned. The fourth
+ argument should point to an unsigned 32-bit integer. If no such value
+ has been set, the call to pcre_fullinfo() returns the error
+ PCRE_ERROR_UNSET.
+
PCRE_INFO_SIZE
- 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.
+ Return the size of the compiled pattern in bytes (for all three
+ 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 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).
+ Return the size in bytes (for all three libraries) 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 argu-
+ ment 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 private, but its length is made available via this
+ option so that it can be saved and restored (see the pcreprecompile
+ documentation for details).
PCRE_INFO_FIRSTCHARACTERFLAGS
Return information about the first data unit of any matched string, for
- a non-anchored pattern. The fourth argument should point to an int
+ a non-anchored pattern. 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), 1 is returned, and the character
+ If there is a fixed first value, for example, the letter "c" from a
+ pattern such as (cat|cow|coyote), 1 is returned, and the character
value can be retrieved using PCRE_INFO_FIRSTCHARACTER.
If there is no fixed first value, and if either
- (a) the pattern was compiled with the PCRE_MULTILINE option, and every
+ (a) the pattern was compiled with the PCRE_MULTILINE option, and every
branch starts with "^", or
(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not
@@ -2859,45 +2978,33 @@ INFORMATION ABOUT A PATTERN
PCRE_INFO_FIRSTCHARACTER
- Return the fixed first character value, if PCRE_INFO_FIRSTCHARACTER-
- FLAGS returned 1; otherwise returns 0. The fourth argument should point
- to an uint_t variable.
+ Return the fixed first character value in the situation where
+ PCRE_INFO_FIRSTCHARACTERFLAGS returns 1; otherwise return 0. The fourth
+ argument should point to an uint_t variable.
- In the 8-bit library, the value is always less than 256. In the 16-bit
- library the value can be up to 0xffff. In the 32-bit library in UTF-32
- mode the value can be up to 0x10ffff, and up to 0xffffffff when not
+ In the 8-bit library, the value is always less than 256. In the 16-bit
+ library the value can be up to 0xffff. In the 32-bit library in UTF-32
+ mode the value can be up to 0x10ffff, and up to 0xffffffff when not
using UTF-32 mode.
- 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
-
- (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not
- set (if it were set, the pattern would be anchored),
-
- -1 is returned, indicating that the pattern matches only at the start
- of a subject string or after any newline within the string. Otherwise
- -2 is returned. For anchored patterns, -2 is returned.
-
PCRE_INFO_REQUIREDCHARFLAGS
- Returns 1 if there is a rightmost literal data unit that must exist in
+ Returns 1 if there is a rightmost literal data unit that must exist in
any matched string, other than at its start. The fourth argument should
- point to an int variable. If there is no such value, 0 is returned. If
+ point to an int variable. If there is no such value, 0 is returned. If
returning 1, the character value itself can be retrieved using
PCRE_INFO_REQUIREDCHAR.
For anchored patterns, a last literal value is recorded only if it fol-
- lows something of variable length. For example, for the pattern
- /^a\d+z\d+/ the returned value 1 (with "z" returned from
+ lows something of variable length. For example, for the pattern
+ /^a\d+z\d+/ the returned value 1 (with "z" returned from
PCRE_INFO_REQUIREDCHAR), but for /^a\dz\d/ the returned value is 0.
PCRE_INFO_REQUIREDCHAR
- 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 uint32_t variable. If
+ 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 uint32_t variable. If
there is no such value, 0 is returned.
@@ -2905,21 +3012,21 @@ 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.)
@@ -2929,22 +3036,22 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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. 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
+ 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
+ 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():
@@ -2963,10 +3070,10 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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;
@@ -2978,13 +3085,13 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
const unsigned char *tables;
unsigned char **mark;
- In the 16-bit version of this structure, the mark field has type
+ In the 16-bit version of this structure, the mark field has type
"PCRE_UCHAR16 **".
- In the 32-bit version of this structure, the mark field has type
+ In the 32-bit version of this structure, the mark field has type
"PCRE_UCHAR32 **".
- The flags field is used to specify which of the other fields are set.
+ The flags field is used to specify which of the other fields are set.
The flag bits are:
PCRE_EXTRA_CALLOUT_DATA
@@ -2995,39 +3102,48 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_EXTRA_STUDY_DATA
PCRE_EXTRA_TABLES
- 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 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
- match, but which have a very large number of possibilities in their
- search trees. The classic example is a pattern that uses nested unlim-
+ 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 unlim-
ited repeats.
- 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
+ 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
+ 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
+ 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.
+ A value for the match limit may also be supplied by an item at the
+ start of a pattern of the form
+
+ (*LIMIT_MATCH=d)
+
+ where d is a decimal number. However, such a setting is ignored unless
+ d is less than the limit set by the caller of pcre_exec() or, if no
+ such limit is set, less than the default.
+
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
@@ -3047,60 +3163,73 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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-
+ A value for the recursion limit may also be supplied by an item at the
+ start of a pattern of the form
+
+ (*LIMIT_RECURSION=d)
+
+ where d is a decimal number. However, such a setting is ignored unless
+ d is less than the limit set by the caller of pcre_exec() or, if no
+ such limit is set, less than the default.
+
+ 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-
- 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-
- 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 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,
+ The tables field is provided for use with patterns that have been pre-
+ compiled using custom character tables, saved to disc or elsewhere, and
+ then reloaded, because the tables that were used to compile a pattern
+ are not saved with it. See the pcreprecompile documentation for a dis-
+ cussion of saving compiled patterns for later use. If NULL is passed
+ using this mechanism, it forces PCRE's internal tables to be used.
+
+ Warning: The tables that pcre_exec() uses must be the same as those
+ that were used when the pattern was compiled. If this is not the case,
+ the behaviour of pcre_exec() is undefined. Therefore, when a pattern is
+ compiled and matched in the same process, this field should never be
+ set. In this (the most common) case, the correct table pointer is auto-
+ matically passed with the compiled pattern from pcre_compile() to
+ pcre_exec().
+
+ 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_HARD, and
+ 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
+ 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
+ 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
- The PCRE_ANCHORED option limits pcre_exec() to matching at the first
- matching position. If a pattern was compiled with PCRE_ANCHORED, or
- turned out to be anchored by virtue of its contents, it cannot be made
+ The PCRE_ANCHORED option limits pcre_exec() to matching at the first
+ matching position. If a pattern was compiled with PCRE_ANCHORED, or
+ turned out to be anchored by virtue of its contents, it cannot be made
unachored at matching time.
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,
- or to match any Unicode newline sequence. These options override the
+ sequence matches. The choice is either to match only CR, LF, or CRLF,
+ or to match any Unicode newline sequence. These options override the
choice that was made or defaulted when the pattern was compiled.
PCRE_NEWLINE_CR
@@ -3109,109 +3238,110 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_NEWLINE_ANYCRLF
PCRE_NEWLINE_ANY
- These options override the newline definition that was chosen or
- defaulted when the pattern was compiled. For details, see the descrip-
- tion of pcre_compile() above. During matching, the newline choice
- affects the behaviour of the dot, circumflex, and dollar metacharac-
- ters. It may also alter the way the match position is advanced after a
+ These options override the newline definition that was chosen or
+ defaulted when the pattern was compiled. For details, see the descrip-
+ tion of pcre_compile() above. During matching, the newline choice
+ affects the behaviour of the dot, circumflex, and dollar metacharac-
+ ters. It may also alter the way the match position is advanced after a
match failure for an unanchored pattern.
- When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is
- set, and a match attempt for an unanchored pattern fails when the cur-
- rent position is at a CRLF sequence, and the pattern contains no
- explicit matches for CR or LF characters, the match position is
+ When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is
+ set, and a match attempt for an unanchored pattern fails when the cur-
+ rent position is at a CRLF sequence, and the pattern contains no
+ explicit matches for CR or LF characters, the match position is
advanced by two characters instead of one, in other words, to after the
CRLF.
The above rule is a compromise that makes the most common cases work as
- expected. For example, if the pattern is .+A (and the PCRE_DOTALL
+ expected. For example, if the pattern is .+A (and the PCRE_DOTALL
option is not set), it does not match the string "\r\nA" because, after
- failing at the start, it skips both the CR and the LF before retrying.
- However, the pattern [\r\n]A does match that string, because it con-
+ failing at the start, it skips both the CR and the LF before retrying.
+ However, the pattern [\r\n]A does match that string, because it con-
tains an explicit CR or LF reference, and so advances only by one char-
acter after the first failure.
An explicit match for CR of LF is either a literal appearance of one of
- those characters, or one of the \r or \n escape sequences. Implicit
- matches such as [^X] do not count, nor does \s (which includes CR and
+ those characters, or one of the \r or \n escape sequences. Implicit
+ matches such as [^X] do not count, nor does \s (which includes CR and
LF in the characters that it matches).
- Notwithstanding the above, anomalous effects may still occur when CRLF
+ Notwithstanding the above, anomalous effects may still occur when CRLF
is a valid newline sequence and explicit \r or \n escapes appear in the
pattern.
PCRE_NOTBOL
This option specifies that first character of the subject string is not
- the beginning of a line, so the circumflex metacharacter should not
- match before it. Setting this without PCRE_MULTILINE (at compile time)
- causes circumflex never to match. This option affects only the behav-
+ the beginning of a line, so the circumflex metacharacter should not
+ match before it. Setting this without PCRE_MULTILINE (at compile time)
+ causes circumflex never to match. This option affects only the behav-
iour of the circumflex metacharacter. It does not affect \A.
PCRE_NOTEOL
This option specifies that the end of the subject string is not the end
- of a line, so the dollar metacharacter should not match it nor (except
- in multiline mode) a newline immediately before it. Setting this with-
+ of a line, so the dollar metacharacter should not match it nor (except
+ in multiline mode) a newline immediately before it. Setting this with-
out PCRE_MULTILINE (at compile time) causes dollar never to match. This
- option affects only the behaviour of the dollar metacharacter. It does
+ option affects only the behaviour of the dollar metacharacter. It does
not affect \Z or \z.
PCRE_NOTEMPTY
An empty string is not considered to be a valid match if this option is
- set. If there are alternatives in the pattern, they are tried. If all
- the alternatives match the empty string, the entire match fails. For
+ set. If there are alternatives in the pattern, they are tried. If all
+ the alternatives match the empty string, the entire match fails. For
example, if the pattern
a?b?
- is applied to a string not beginning with "a" or "b", it matches an
- empty string at the start of the subject. With PCRE_NOTEMPTY set, this
+ is applied to a string not beginning with "a" or "b", it matches an
+ empty string at the start of the subject. With PCRE_NOTEMPTY set, this
match is not valid, so PCRE searches further into the string for occur-
rences of "a" or "b".
PCRE_NOTEMPTY_ATSTART
- This is like PCRE_NOTEMPTY, except that an empty string match that is
- not at the start of the subject is permitted. If the pattern is
+ This is like PCRE_NOTEMPTY, except that an empty string match that is
+ not at the start of the subject is permitted. If the pattern is
anchored, such a match can occur only if the pattern contains \K.
- Perl has no direct equivalent of PCRE_NOTEMPTY or
- PCRE_NOTEMPTY_ATSTART, but it does make a special case of a pattern
- match of the empty string within its split() function, and when using
- the /g modifier. It is possible to emulate Perl's behaviour after
+ Perl has no direct equivalent of PCRE_NOTEMPTY or
+ PCRE_NOTEMPTY_ATSTART, but it does make a special case of a pattern
+ match of the empty string within its split() function, and when using
+ the /g modifier. It is possible to emulate Perl's behaviour after
matching a null string by first trying the match again at the same off-
- set with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then if that
+ set with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then if that
fails, by advancing the starting offset (see below) and trying an ordi-
- nary match again. There is some code that demonstrates how to do this
- in the pcredemo 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 the current character is CR followed by LF, advance the
+ nary match again. There is some code that demonstrates how to do this
+ in the pcredemo 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 the current character is CR followed by LF, advance the
starting offset by two characters instead of one.
PCRE_NO_START_OPTIMIZE
- There are a number of optimizations that pcre_exec() uses at the start
- of a match, in order to speed up the process. For example, if it is
+ There are a number of optimizations that pcre_exec() uses at the start
+ of a match, in order to speed up the process. For example, if it is
known that an unanchored match must start with a specific character, it
- searches the subject for that character, and fails immediately if it
- cannot find it, without actually running the main matching function.
+ searches the subject for that character, and fails immediately if it
+ cannot find it, without actually running the main matching function.
This means that a special item such as (*COMMIT) at the start of a pat-
- tern is not considered until after a suitable starting point for the
- match has been found. When callouts or (*MARK) items are in use, these
- "start-up" optimizations can cause them to be skipped if the pattern is
- never actually used. The start-up optimizations are in effect a pre-
- scan of the subject that takes place before the pattern is run.
-
- The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations,
- possibly causing performance to suffer, but ensuring that in cases
- where the result is "no match", the callouts do occur, and that items
+ tern is not considered until after a suitable starting point for the
+ match has been found. Also, when callouts or (*MARK) items are in use,
+ these "start-up" optimizations can cause them to be skipped if the pat-
+ tern is never actually used. The start-up optimizations are in effect a
+ pre-scan of the subject that takes place before the pattern is run.
+
+ The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations,
+ possibly causing performance to suffer, but ensuring that in cases
+ 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. The use of
- PCRE_NO_START_OPTIMIZE disables JIT execution; when it is set, matching
- is always done using interpretively.
+ position in the subject string. If PCRE_NO_START_OPTIMIZE is set at
+ compile time, it cannot be unset at matching time. The use of
+ PCRE_NO_START_OPTIMIZE at matching time (that is, passing it to
+ pcre_exec()) disables JIT execution; in this situation, matching is
+ always done using interpretively.
Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching
operation. Consider the pattern
@@ -3267,7 +3397,7 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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.
+ may crash or loop.
PCRE_PARTIAL_HARD
PCRE_PARTIAL_SOFT
@@ -3297,149 +3427,156 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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,
+ length in length, and a starting offset in startoffset. The units for
+ length and startoffset are bytes for the 8-bit library, 16-bit data
+ items for the 16-bit library, and 32-bit data items for the 32-bit
+ library.
+
+ If startoffset 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
- 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
+ and this is by far the most common case. In UTF-8 or UTF-16 mode, the
+ offset must point to the start of a character, or the end of the sub-
+ ject (in UTF-32 mode, one data unit equals one character, so all off-
+ sets are valid). Unlike the pattern string, the subject may contain
+ binary zeroes.
+
+ 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
- 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
+ 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 offset of the first character in a
+ substring, and the second is set to the offset of the first character
+ after the end of a substring. These values are always data unit off-
+ sets, even in UTF mode. They are byte offsets in the 8-bit library,
+ 16-bit data item offsets in the 16-bit library, and 32-bit data item
+ offsets in the 32-bit library. Note: 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
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 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
+ 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
+ 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
+ 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
+ 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
+ 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 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
+ 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)
@@ -3448,7 +3585,7 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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)
@@ -3457,82 +3594,82 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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, 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
+ 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),
+ 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 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-
+ 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)
@@ -3542,7 +3679,7 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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)
@@ -3556,29 +3693,29 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
PCRE_ERROR_SHORTUTF8 (-25)
- 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-
+ 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
+ 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,
+ 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
+ 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)
@@ -3588,38 +3725,38 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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
+ 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.
PCRE_ERROR_JIT_BADOPTION
- This error is returned when a pattern that was successfully studied
- using a JIT compile option is being matched, but the matching mode
- (partial or complete match) does not correspond to any JIT compilation
- mode. When the JIT fast path function is used, this error may be also
- given for invalid options. See the pcrejit documentation for more
+ This error is returned when a pattern that was successfully studied
+ using a JIT compile option is being matched, but the matching mode
+ (partial or complete match) does not correspond to any JIT compilation
+ mode. When the JIT fast path function is used, this error may be also
+ given for invalid options. See the pcrejit documentation for more
details.
PCRE_ERROR_BADLENGTH (-32)
- This error is given if pcre_exec() is called with a negative value for
+ This error is given if pcre_exec() is called with a negative value for
the length argument.
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 and 32-bit libraries is given in the pcre16
+ This section applies only to the 8-bit library. The corresponding
+ information for the 16-bit and 32-bit libraries is given in the pcre16
and pcre32 pages.
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
+ 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 second element (ovector[1]). The reason codes are given names in
the pcre.h header file:
PCRE_UTF8_ERR1
@@ -3628,10 +3765,10 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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
+ 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
@@ -3641,24 +3778,24 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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
+ 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
+ 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
+ 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
+ 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
@@ -3667,28 +3804,29 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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-
+ 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-
+ 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.
PCRE_UTF8_ERR21
- The first byte of a character has the value 0xfe or 0xff. These values
+ The first byte of a character has the value 0xfe or 0xff. These values
can never occur in a valid UTF-8 string.
- PCRE_UTF8_ERR2
+ PCRE_UTF8_ERR22
- Non-character. These are the last two characters in each plane (0xfffe,
- 0xffff, 0x1fffe, 0x1ffff .. 0x10fffe, 0x10ffff), and the characters
- 0xfdd0..0xfdef.
+ This error code was formerly used when the presence of a so-called
+ "non-character" caused an error. Unicode corrigendum #9 makes it clear
+ that such characters should not cause a string to be rejected, and so
+ this code is no longer in use and is never returned.
EXTRACTING CAPTURED SUBSTRINGS BY NUMBER
@@ -4039,55 +4177,64 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION
filled with the longest matches. Unlike pcre_exec(), pcre_dfa_exec()
can use the entire ovector for returning matched strings.
+ NOTE: PCRE's "auto-possessification" optimization usually applies to
+ character repeats at the end of a pattern (as well as internally). For
+ example, the pattern "a\d+" is compiled as if it were "a\d++" because
+ there is no point even considering the possibility of backtracking into
+ the repeated digits. For DFA matching, this means that only one possi-
+ ble match is found. If you really do want multiple matches in such
+ cases, either use an ungreedy repeat ("a\d+?") or set the
+ PCRE_NO_AUTO_POSSESS option when compiling.
+
Error returns from pcre_dfa_exec()
- The pcre_dfa_exec() function returns a negative number when it fails.
- Many of the errors are the same as for pcre_exec(), and these are
- described above. There are in addition the following errors that are
+ The pcre_dfa_exec() function returns a negative number when it fails.
+ Many of the errors are the same as for pcre_exec(), and these are
+ described above. There are in addition the following errors that are
specific to pcre_dfa_exec():
PCRE_ERROR_DFA_UITEM (-16)
- This return is given if pcre_dfa_exec() encounters an item in the pat-
- tern that it does not support, for instance, the use of \C or a back
+ This return is given if pcre_dfa_exec() encounters an item in the pat-
+ tern that it does not support, for instance, the use of \C or a back
reference.
PCRE_ERROR_DFA_UCOND (-17)
- This return is given if pcre_dfa_exec() encounters a condition item
- that uses a back reference for the condition, or a test for recursion
+ This return is given if pcre_dfa_exec() encounters a condition item
+ that uses a back reference for the condition, or a test for recursion
in a specific group. These are not supported.
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 or match_limit_recursion
- fields. This is not supported (these fields are meaningless for DFA
+ This return is given if pcre_dfa_exec() is called with an extra 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)
- 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
+ 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
- pcre16(3), pcre32(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3),
+ pcre16(3), pcre32(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3),
pcrematching(3), pcrepartial(3), pcreposix(3), pcreprecompile(3), pcre-
sample(3), pcrestack(3).
@@ -4101,18 +4248,18 @@ AUTHOR
REVISION
- Last updated: 08 November 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 12 November 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCRECALLOUT(3) PCRECALLOUT(3)
+PCRECALLOUT(3) Library Functions Manual PCRECALLOUT(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
SYNOPSIS
#include <pcre.h>
@@ -4153,48 +4300,88 @@ DESCRIPTION
(?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
- optimize the performance of a particular pattern.
+ alternation bar. If the pattern contains a conditional group whose con-
+ dition is an assertion, an automatic callout is inserted immediately
+ before the condition. Such a callout may also be inserted explicitly,
+ for example:
+
+ (?(?C9)(?=a)ab|de)
+
+ This applies only to assertion conditions (because they are themselves
+ independent groups).
- 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.
+ Automatic callouts can be used for tracking the progress of pattern
+ matching. The pcretest program has a pattern qualifier (/C) that sets
+ automatic callouts; when it is used, the output indicates how the pat-
+ tern is being matched. This is useful information when you are trying
+ to optimize the performance of a particular pattern.
MISSING CALLOUTS
- 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
+ You should be aware that, because of optimizations in the way PCRE com-
+ piles and matches patterns, callouts sometimes do not happen exactly as
+ you might expect.
+
+ At compile time, PCRE "auto-possessifies" repeated items when it knows
+ that what follows cannot be part of the repeat. For example, a+[bc] is
+ compiled as if it were a++[bc]. The pcretest output when this pattern
+ is anchored and then applied with automatic callouts to the string
+ "aaaa" is:
+
+ --->aaaa
+ +0 ^ ^
+ +1 ^ a+
+ +3 ^ ^ [bc]
+ No match
+
+ This indicates that when matching [bc] fails, there is no backtracking
+ into a+ and therefore the callouts that would be taken for the back-
+ tracks do not occur. You can disable the auto-possessify feature by
+ passing PCRE_NO_AUTO_POSSESS to pcre_compile(), or starting the pattern
+ with (*NO_AUTO_POSSESS). If this is done in pcretest (using the /O
+ qualifier), the output changes to this:
+
+ --->aaaa
+ +0 ^ ^
+ +1 ^ a+
+ +3 ^ ^ [bc]
+ +3 ^ ^ [bc]
+ +3 ^ ^ [bc]
+ +3 ^^ [bc]
+ No match
+
+ This time, when matching [bc] fails, the matcher backtracks into a+ and
+ tries again, repeatedly, until a+ itself fails.
+
+ Other optimizations that provide fast "no match" results also affect
+ callouts. 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 the matching function, or by starting the pattern with
- (*NO_START_OPT). This slows down the matching process, but does ensure
+ 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-
+ During matching, when PCRE reaches a callout point, the external func-
tion defined by pcre_callout or pcre[16|32]_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
- pcre[16|32]_callout block. These structures contains the following
+ set). This applies to both normal and DFA matching. The only argument
+ to the callout function is a pointer to a pcre_callout or
+ pcre[16|32]_callout block. These structures contains the following
fields:
int version;
@@ -4215,44 +4402,47 @@ THE CALLOUT INTERFACE
const PCRE_UCHAR16 *mark; (16-bit version)
const PCRE_UCHAR32 *mark; (32-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 2. The
- version number will change again in future if additional fields are
+ The version field is an integer containing the version number of 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.
- The callout_number field contains the number of the callout, as com-
- piled into the pattern (that is, the number after ?C for manual call-
+ The callout_number field contains the number of the callout, as com-
+ piled into the pattern (that is, the number after ?C for manual call-
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 the matching function. When pcre_exec() or
- pcre[16|32]_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
+ The offset_vector field is a pointer to the vector of offsets that was
+ passed by the caller to the matching function. When pcre_exec() or
+ pcre[16|32]_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 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
- sequence \K has been encountered, this value is changed to reflect the
- modified starting point. If the pattern is not anchored, the callout
+ The start_match field normally contains the offset within the subject
+ at which the current match attempt started. However, if the escape
+ sequence \K has been encountered, this value is changed to reflect the
+ modified starting point. If the pattern is not anchored, the callout
function may be called several times from the same point in the pattern
for different starting points in the subject.
- The current_position field contains the offset within the subject of
+ The current_position field contains the offset within the subject of
the current match pointer.
- When the pcre_exec() or pcre[16|32]_exec() is used, the capture_top
- field contains one more than the number of the highest numbered cap-
- tured 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
+ When the pcre_exec() or pcre[16|32]_exec() is used, the capture_top
+ field contains one more than the number of the highest numbered cap-
+ tured 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 cap-
- tured substring. If no substrings have been captured, its value is -1.
- This is always the case for the DFA matching functions.
+ The capture_last field contains the number of the most recently cap-
+ tured substring. However, when a recursion exits, the value reverts to
+ what it was outside the recursion, as do the values of all captured
+ substrings. If no substrings have been captured, the value of cap-
+ ture_last is -1. This is always the case for the DFA matching func-
+ tions.
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
@@ -4310,18 +4500,18 @@ AUTHOR
REVISION
- Last updated: 24 June 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 12 November 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCRECOMPAT(3) PCRECOMPAT(3)
+PCRECOMPAT(3) Library Functions Manual PCRECOMPAT(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
DIFFERENCES BETWEEN PCRE AND PERL
This document describes the differences in the ways that PCRE and Perl
@@ -4340,10 +4530,8 @@ DIFFERENCES BETWEEN PCRE AND PERL
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
- branch.
+ set. Perl sometimes (but not always) sets its numerical variables from
+ inside negative assertions.
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-
@@ -4398,24 +4586,30 @@ DIFFERENCES BETWEEN PCRE AND 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. 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.
-
- 11. There are some differences that are concerned with the settings of
+ 10. If any of the backtracking control verbs are used 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 sur-
+ rounding 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. Note that such subpatterns are processed as anchored at
+ the point where they are tested.
+
+ 11. If a pattern contains more than one backtracking control verb, the
+ first one that is backtracked onto acts. For example, in the pattern
+ A(*COMMIT)B(*PRUNE)C a failure in B triggers (*COMMIT), but a failure
+ in C triggers (*PRUNE). Perl's behaviour is more complex; in many cases
+ it is the same as PCRE, but there are examples where it differs.
+
+ 12. Most backtracking verbs in assertions have their normal actions.
+ They are not confined to the assertion.
+
+ 13. 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".
- 12. PCRE's handling of duplicate subpattern numbers and duplicate sub-
+ 14. 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
@@ -4426,29 +4620,42 @@ DIFFERENCES BETWEEN PCRE AND PERL
turing subpattern number 1. To avoid this confusing situation, an error
is given at compile time.
- 13. Perl recognizes comments in some places that PCRE does not, for
+ 15. 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.
-
- 14. PCRE provides some extensions to the Perl regular expression facil-
- ities. Perl 5.10 includes new features that are not in earlier ver-
- sions of Perl, some of which (such as named parentheses) have been in
+ modifier is set, Perl allows white space between ( and ? (though cur-
+ rent Perls warn that this is deprecated) but PCRE never does, even if
+ the PCRE_EXTENDED option is set.
+
+ 16. Perl, when in warning mode, gives warnings for character classes
+ such as [A-\d] or [a-[:digit:]]. It then treats the hyphens as liter-
+ als. PCRE has no warning features, so it gives an error in these cases
+ because they are almost certainly user mistakes.
+
+ 17. In PCRE, the upper/lower case character properties Lu and Ll are
+ not affected when case-independent matching is specified. For example,
+ \p{Lu} always matches an upper case letter. I think Perl has changed in
+ this respect; in the release at the time of writing (5.16), \p{Lu} and
+ \p{Ll} match all letters, regardless of case, when case independence is
+ specified.
+
+ 18. PCRE provides some extensions to the Perl regular expression facil-
+ ities. Perl 5.10 includes new features that are not in earlier ver-
+ sions 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:
- (a) Although lookbehind assertions in PCRE must match fixed length
- strings, each alternative branch of a lookbehind assertion can match a
- different length of string. Perl requires them all to have the same
+ (a) Although lookbehind assertions in PCRE must match fixed length
+ strings, each alternative branch of a lookbehind assertion can match a
+ different length of string. Perl requires them all to have the same
length.
- (b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is not set, the $
+ (b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is not set, the $
meta-character matches only at the very end of the string.
(c) If PCRE_EXTRA is set, a backslash followed by a letter with no spe-
cial meaning is faulted. Otherwise, like Perl, the backslash is quietly
ignored. (Perl can be made to issue a warning.)
- (d) If PCRE_UNGREEDY is set, the greediness of the repetition quanti-
+ (d) If PCRE_UNGREEDY is set, the greediness of the repetition quanti-
fiers is inverted, that is, by default they are not greedy, but if fol-
lowed by a question mark they are.
@@ -4456,10 +4663,10 @@ DIFFERENCES BETWEEN PCRE AND PERL
tried only at the first matching position in the subject string.
(f) The PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART,
- and PCRE_NO_AUTO_CAPTURE options for pcre_exec() have no Perl equiva-
+ and PCRE_NO_AUTO_CAPTURE options for pcre_exec() have no Perl equiva-
lents.
- (g) The \R escape sequence can be restricted to match only CR, LF, or
+ (g) The \R escape sequence can be restricted to match only CR, LF, or
CRLF by the PCRE_BSR_ANYCRLF option.
(h) The callout facility is PCRE-specific.
@@ -4467,14 +4674,14 @@ DIFFERENCES BETWEEN PCRE AND PERL
(i) The partial matching facility is PCRE-specific.
(j) Patterns compiled by PCRE can be saved and re-used at a later time,
- even on different hosts that have the other endianness. However, this
+ even on 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 functions (pcre_dfa_exec(),
- pcre16_dfa_exec() and pcre32_dfa_exec(),) match in a different way and
+ pcre16_dfa_exec() and pcre32_dfa_exec(),) match in a different way and
are not Perl-compatible.
- (l) PCRE recognizes some special sequences such as (*CR) at the start
+ (l) PCRE recognizes some special sequences such as (*CR) at the start
of a pattern that set overall options that cannot be changed within the
pattern.
@@ -4488,18 +4695,18 @@ AUTHOR
REVISION
- Last updated: 25 August 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 10 November 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCREPATTERN(3) PCREPATTERN(3)
+PCREPATTERN(3) Library Functions Manual PCREPATTERN(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
PCRE REGULAR EXPRESSION DETAILS
The syntax and semantics of the regular expressions that are supported
@@ -4517,6 +4724,29 @@ PCRE REGULAR EXPRESSION DETAILS
great detail. This description of PCRE's regular expressions is
intended as reference material.
+ This document discusses the patterns that are supported by PCRE when
+ one its main matching functions, pcre_exec() (8-bit) or
+ pcre[16|32]_exec() (16- or 32-bit), is used. PCRE also has alternative
+ matching functions, pcre_dfa_exec() and pcre[16|32_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.
+
+
+SPECIAL START-OF-PATTERN ITEMS
+
+ A number of options that can be passed to pcre_compile() can also be
+ set by special items at the start of a pattern. These are not Perl-com-
+ patible, but are provided to make these options accessible to pattern
+ writers who are not able to change the program that processes the pat-
+ tern. Any number of these items may appear, but they must all be
+ together right at the start of the pattern string, and the letters must
+ be in upper case.
+
+ UTF support
+
The original operation of PCRE was on strings of one-byte characters.
However, there is now also support for UTF-8 strings in the original
library, an extra library that supports 16-bit and UTF-16 character
@@ -4533,47 +4763,39 @@ PCRE REGULAR EXPRESSION DETAILS
(*UTF) is a generic sequence that can be used with any of the
libraries. 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 features in the pcreunicode
- page.
+ setting the relevant option. How setting a UTF mode affects pattern
+ matching is mentioned in several places below. There is also a summary
+ of features in the pcreunicode page.
- Another special sequence that may appear at the start of a pattern or
- in combination with (*UTF8), (*UTF16), (*UTF32) or (*UTF) is:
+ Some applications that allow their users to supply patterns may wish to
+ restrict them to non-UTF data for security reasons. If the
+ PCRE_NEVER_UTF option is set at compile time, (*UTF) etc. are not
+ allowed, and their appearance causes an error.
- (*UCP)
+ Unicode property support
- This has the same effect as setting the PCRE_UCP option: it causes
- sequences such as \d and \w to use Unicode properties to determine
- character types, instead of recognizing only characters with codes less
- than 128 via a lookup table.
+ Another special sequence that may appear at the start of a pattern is
+ (*UCP). This has the same effect as setting the PCRE_UCP option: it
+ causes sequences such as \d and \w to use Unicode properties to deter-
+ mine character types, instead of recognizing only characters with codes
+ less than 128 via a lookup table.
- If a pattern starts with (*NO_START_OPT), it has the same effect as
- setting the PCRE_NO_START_OPTIMIZE option either at compile or matching
- time. There are also some more of these special sequences that are con-
- cerned with the handling of newlines; they are described below.
+ Disabling auto-possessification
- The remainder of this document discusses the patterns that are sup-
- ported by PCRE when one its main matching functions, pcre_exec()
- (8-bit) or pcre[16|32]_exec() (16- or 32-bit), is used. PCRE also has
- alternative matching functions, pcre_dfa_exec() and
- pcre[16|32_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 func-
- tions, are discussed in the pcrematching page.
+ If a pattern starts with (*NO_AUTO_POSSESS), it has the same effect as
+ setting the PCRE_NO_AUTO_POSSESS option at compile time. This stops
+ PCRE from making quantifiers possessive when what follows cannot match
+ the repeated item. For example, by default a+b is treated as a++b. For
+ more details, see the pcreapi documentation.
+ Disabling start-up optimizations
-EBCDIC CHARACTER CODES
-
- PCRE can be compiled to run in an environment that uses EBCDIC as its
- character code rather than ASCII or Unicode (typically a mainframe sys-
- tem). In the sections below, character code values are ASCII or Uni-
- code; in an EBCDIC environment these characters may have different code
- values, and there are no code points greater than 255.
-
+ If a pattern starts with (*NO_START_OPT), it has the same effect as
+ setting the PCRE_NO_START_OPTIMIZE option either at compile or matching
+ time. This disables several optimizations for quickly reaching "no
+ match" results. For more details, see the pcreapi documentation.
-NEWLINE CONVENTIONS
+ Newline conventions
PCRE supports five different conventions for indicating line breaks in
strings: a single CR (carriage return) character, a single LF (line-
@@ -4598,10 +4820,8 @@ NEWLINE CONVENTIONS
(*CR)a.b
changes the convention to CR. That pattern matches "a\nb" because LF is
- no longer a newline. 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.
+ no longer a newline. If more than one of these settings is present, the
+ last one is used.
The newline convention affects where the circumflex and dollar asser-
tions are true. It also affects the interpretation of the dot metachar-
@@ -4612,6 +4832,36 @@ NEWLINE CONVENTIONS
line sequences" below. A change of \R setting can be combined with a
change of newline convention.
+ Setting match and recursion limits
+
+ The caller of pcre_exec() can set a limit on the number of times the
+ internal match() function is called and on the maximum depth of recur-
+ sive calls. These facilities are provided to catch runaway matches that
+ are provoked by patterns with huge matching trees (a typical example is
+ a pattern with nested unlimited repeats) and to avoid running out of
+ system stack by too much recursion. When one of these limits is
+ reached, pcre_exec() gives an error return. The limits can also be set
+ by items at the start of the pattern of the form
+
+ (*LIMIT_MATCH=d)
+ (*LIMIT_RECURSION=d)
+
+ where d is any number of decimal digits. However, the value of the set-
+ ting must be less than the value set (or defaulted) by the caller of
+ pcre_exec() for it to have any effect. In other words, the pattern
+ writer can lower the limits set by the programmer, but not raise them.
+ If there is more than one setting of one of these limits, the lower
+ value is used.
+
+
+EBCDIC CHARACTER CODES
+
+ PCRE can be compiled to run in an environment that uses EBCDIC as its
+ character code rather than ASCII or Unicode (typically a mainframe sys-
+ tem). In the sections below, character code values are ASCII or Uni-
+ code; in an EBCDIC environment these characters may have different code
+ values, and there are no code points greater than 255.
+
CHARACTERS AND METACHARACTERS
@@ -4689,11 +4939,11 @@ BACKSLASH
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, 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 escap-
- ing backslash can be used to include a white space or # character as
- part of the pattern.
+ If a pattern is compiled with the PCRE_EXTENDED option, most white
+ space in the pattern (other than in a character class), and characters
+ between a # outside a character class and the next newline, inclusive,
+ are ignored. An escaping backslash can 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 charac-
ters, you can do so by putting them between \Q and \E. This is differ-
@@ -4731,7 +4981,9 @@ BACKSLASH
\n linefeed (hex 0A)
\r carriage return (hex 0D)
\t tab (hex 09)
+ \0dd character with octal code 0dd
\ddd character with octal code ddd, or back reference
+ \o{ddd..} character with octal code ddd..
\xhh character with hex code hh
\x{hhh..} character with hex code hhh.. (non-JavaScript mode)
\uhhhh character with hex code hhhh (JavaScript mode only)
@@ -4754,61 +5006,38 @@ BACKSLASH
are disjoint, \cZ becomes hex 29 (Z is E9), and other characters also
generate different values.
- By default, after \x, from zero to two hexadecimal digits are read
- (letters can be in upper or lower case). Any number of hexadecimal dig-
- its 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
- 32-bit non-UTF mode less than 0x80000000
- 32-bit UTF-32 mode less than 0x10ffff and a valid codepoint
-
- Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-
- called "surrogate" codepoints), and 0xffef.
-
- If characters other than hexadecimal digits appear between \x{ and },
- or if there is no terminating }, this form of escape is not recognized.
- Instead, the initial \x will be interpreted as a basic hexadecimal
- escape, with no 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 dig-
- its. 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 (or by \u in JavaScript mode). There is no differ-
- ence 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 digits, just those that are present are used. Thus the
sequence \0\x\07 specifies two binary zeros followed by a BEL character
(code value 7). Make sure you supply two digits after the initial zero
if the pattern character that follows is itself an octal digit.
+ The escape \o must be followed by a sequence of octal digits, enclosed
+ in braces. An error occurs if this is not the case. This escape is a
+ recent addition to Perl; it provides way of specifying character code
+ points as octal numbers greater than 0777, and it also allows octal
+ numbers and back references to be unambiguously specified.
+
+ For greater clarity and unambiguity, it is best to avoid following \ by
+ a digit greater than zero. Instead, use \o{} or \x{} to specify charac-
+ ter numbers, and \g{} to specify back references. The following para-
+ graphs describe the old, ambiguous syntax.
+
The handling of a backslash followed by a digit other than 0 is compli-
- cated. Outside a character class, PCRE reads it and any following dig-
- its as a decimal number. If the number is less than 10, or if there
- have been at least that many previous capturing left parentheses in the
- expression, the entire sequence is taken as a back reference. A
+ cated, and Perl has changed in recent releases, causing PCRE also to
+ change. Outside a character class, PCRE reads the digit and any follow-
+ ing digits as a decimal number. If the number is less than 8, or if
+ there have been at least that many previous capturing left parentheses
+ in the expression, the entire sequence is taken as a back reference. A
description of how this works is given later, following the discussion
of parenthesized subpatterns.
- 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 gen-
- erate a data character. Any subsequent digits stand for themselves. The
- value of the character is constrained in the same way as characters
- specified in hexadecimal. For example:
+ Inside a character class, or if the decimal number following \ is
+ greater than 7 and there have not been that many capturing subpatterns,
+ PCRE handles \8 and \9 as the literal characters "8" and "9", and oth-
+ erwise re-reads up to three octal digits following the backslash, using
+ them to generate a data character. Any subsequent digits stand for
+ themselves. For example:
\040 is another way of writing an ASCII space
\40 is the same, provided there are fewer than 40
@@ -4822,45 +5051,81 @@ BACKSLASH
character with octal code 113
\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"
+ \81 is either a back reference, or the two
+ characters "8" and "1"
+
+ Note that octal values of 100 or greater that are specified using this
+ syntax must not be introduced by a leading zero, because no more than
+ three octal digits are ever read.
+
+ By default, after \x that is not followed by {, from zero to two hexa-
+ decimal digits are read (letters can be in upper or lower case). Any
+ number of hexadecimal digits may appear between \x{ and }. If a charac-
+ ter other than a hexadecimal digit appears between \x{ and }, or if
+ there is no terminating }, an error occurs.
+
+ If the PCRE_JAVASCRIPT_COMPAT option is set, the interpretation of \x
+ is as just described only when it is followed by two hexadecimal dig-
+ its. 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.
+
+ Characters whose value is less than 256 can be defined by either of the
+ two syntaxes for \x (or by \u in JavaScript mode). There is no differ-
+ ence in the way they are handled. For example, \xdc is exactly the same
+ as \x{dc} (or \u00dc in JavaScript mode).
- Note that octal values of 100 or greater must not be introduced by a
- leading zero, because no more than three octal digits are ever read.
+ Constraints on character values
+
+ Characters that are specified using octal or hexadecimal numbers are
+ limited to certain values, 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
+ 32-bit non-UTF mode less than 0x100000000
+ 32-bit UTF-32 mode less than 0x10ffff and a valid codepoint
+
+ Invalid Unicode codepoints are the range 0xd800 to 0xdfff (the so-
+ called "surrogate" codepoints), and 0xffef.
+
+ Escape sequences in character classes
All the sequences that define a single character value can be used both
- inside and outside character classes. In addition, inside a character
+ inside 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
+ \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
+ 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
- The sequence \g followed by an unsigned or a negative number, option-
- ally enclosed in braces, is an absolute or relative back reference. A
+ The sequence \g followed by an unsigned or a negative number, option-
+ ally enclosed in braces, is an absolute or relative back reference. A
named back reference can be coded as \g{name}. Back references are dis-
cussed later, following the discussion of parenthesized subpatterns.
Absolute and relative subroutine calls
- For compatibility with Oniguruma, the non-Perl syntax \g followed by a
+ For compatibility with Oniguruma, the non-Perl syntax \g followed by a
name or a number enclosed either in angle brackets or single quotes, is
- an alternative syntax for referencing a subpattern as a "subroutine".
- Details are discussed later. Note that \g{...} (Perl syntax) and
- \g<...> (Oniguruma syntax) are not synonymous. The former is a back
+ an alternative syntax for referencing a subpattern as a "subroutine".
+ Details are discussed later. Note that \g{...} (Perl syntax) and
+ \g<...> (Oniguruma syntax) are not synonymous. The former is a back
reference; the latter is a subroutine call.
Generic character types
@@ -4879,44 +5144,49 @@ BACKSLASH
\W any "non-word" character
There is also the single sequence \N, which matches a non-newline char-
- acter. This is the same as the "." metacharacter when PCRE_DOTALL is
- not set. Perl also uses \N to match characters by name; PCRE does not
+ acter. This is the same as the "." metacharacter 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 com-
- plete set of characters into two disjoint sets. Any given character
- matches one, and only one, of each pair. The sequences can appear both
- inside and outside character classes. They each match one character of
- the appropriate type. If the current matching point is at the end of
- the subject string, all of them fail, because there is no character to
+ Each pair of lower and upper case escape sequences partitions the com-
+ plete set of characters into two disjoint sets. Any given character
+ matches one, and only one, of each pair. The sequences can appear both
+ inside and outside character classes. They each match one character of
+ the appropriate type. If the current matching point is at the end of
+ the subject string, all of them fail, because there is no character to
match.
- For compatibility with Perl, \s does not match the VT character (code
- 11). This makes it different from the the POSIX "space" class. The \s
- characters are HT (9), LF (10), FF (12), CR (13), and space (32). If
- "use locale;" is included in a Perl script, \s may match the VT charac-
- ter. In PCRE, it never does.
-
- A "word" character is an underscore or any character that is a letter
- or digit. By default, the definition of letters and digits is con-
- trolled by PCRE's low-valued character tables, and may vary if locale-
- specific matching is taking place (see "Locale support" in the pcreapi
- page). For example, in a French locale such as "fr_FR" in Unix-like
- systems, or "french" in Windows, some character codes greater than 128
- are used for accented letters, and these are then matched by \w. The
+ For compatibility with Perl, \s did not used to match the VT character
+ (code 11), which made it different from the the POSIX "space" class.
+ However, Perl added VT at release 5.18, and PCRE followed suit at
+ release 8.34. The default \s characters are now HT (9), LF (10), VT
+ (11), FF (12), CR (13), and space (32), which are defined as white
+ space in the "C" locale. This list may vary if locale-specific matching
+ is taking place. For example, in some locales the "non-breaking space"
+ character (\xA0) is recognized as white space, and in others the VT
+ character is not.
+
+ A "word" character is an underscore or any character that is a letter
+ or digit. By default, the definition of letters and digits is con-
+ trolled by PCRE's low-valued character tables, and may vary if locale-
+ specific matching is taking place (see "Locale support" in the pcreapi
+ page). For example, in a French locale such as "fr_FR" in Unix-like
+ systems, or "french" in Windows, some character codes greater than 127
+ are used for accented letters, and these are then matched by \w. The
use of locales with Unicode is discouraged.
- 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 support was
- available, mainly for efficiency reasons. However, if PCRE is compiled
- with Unicode property support, and the PCRE_UCP option is set, the be-
- haviour is changed so that Unicode properties are used to determine
- character types, as follows:
+ By default, characters whose code points are greater than 127 never
+ match \d, \s, or \w, and always match \D, \S, and \W, although this may
+ vary for characters in the range 128-255 when locale-specific matching
+ is happening. These escape sequences retain their original meanings
+ from before Unicode support was available, mainly for efficiency rea-
+ sons. If PCRE is compiled with Unicode property support, and the
+ PCRE_UCP option is set, the behaviour is changed so that Unicode prop-
+ erties are used to determine character types, as follows:
- \d any character that \p{Nd} matches (decimal digit)
- \s any character that \p{Z} matches, plus HT, LF, FF, CR
- \w any character that \p{L} or \p{N} matches, plus underscore
+ \d any character that matches \p{Nd} (decimal digit)
+ \s any character that matches \p{Z} or \h or \v
+ \w any character that matches \p{L} or \p{N}, plus underscore
The upper case escapes match the inverse sets of characters. Note that
\d matches only decimal digits, whereas \w matches any Unicode digit,
@@ -4927,7 +5197,7 @@ BACKSLASH
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, whether or not PCRE_UCP is set. The horizontal space char-
+ code points, whether or not PCRE_UCP is set. The horizontal space char-
acters are:
U+0009 Horizontal tab (HT)
@@ -5136,52 +5406,53 @@ BACKSLASH
in the Unicode table.
Specifying caseless matching does not affect these escape sequences.
- For example, \p{Lu} always matches only upper case letters.
+ For example, \p{Lu} always matches only upper case letters. This is
+ different from the behaviour of current versions of Perl.
- Matching characters by Unicode property is not fast, because PCRE has
- to do a multistage table lookup in order to find a character's prop-
+ Matching characters by Unicode property is not fast, because PCRE has
+ to do a multistage table lookup in order to find a character's prop-
erty. 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 or by starting the pattern with
+ do so by setting the PCRE_UCP option or by starting the pattern with
(*UCP).
Extended grapheme clusters
- 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 grapheme cluster", and treats the sequence as an atomic group
- (see below). Up to and including release 8.31, PCRE matched an ear-
+ (see below). Up to and including release 8.31, PCRE matched an ear-
lier, simpler definition that was equivalent to
(?>\PM\pM*)
- That is, it matched a character without the "mark" property, followed
- by zero or more characters with the "mark" property. Characters with
- the "mark" property are typically non-spacing accents that affect the
+ That is, it matched a character without the "mark" property, followed
+ by zero or more characters with the "mark" property. Characters with
+ the "mark" property are typically non-spacing accents that affect the
preceding character.
- This simple definition was extended in Unicode to include more compli-
- cated kinds of composite character by giving each character a grapheme
- breaking property, and creating rules that use these properties to
- define the boundaries of extended grapheme clusters. In releases of
+ This simple definition was extended in Unicode to include more compli-
+ cated kinds of composite character by giving each character a grapheme
+ breaking property, and creating rules that use these properties to
+ define the boundaries of extended grapheme clusters. In releases of
PCRE later than 8.31, \X matches one of these clusters.
- \X always matches at least one character. Then it decides whether to
+ \X always matches at least one character. Then it decides whether to
add additional characters according to the following rules for ending a
cluster:
1. End at the end of the subject string.
- 2. Do not end between CR and LF; otherwise end after any control char-
+ 2. Do not end between CR and LF; otherwise end after any control char-
acter.
- 3. Do not break Hangul (a Korean script) syllable sequences. Hangul
- characters are of five types: L, V, T, LV, and LVT. An L character may
- be followed by an L, V, LV, or LVT character; an LV or V character may
+ 3. Do not break Hangul (a Korean script) syllable sequences. Hangul
+ characters are of five types: L, V, T, LV, and LVT. An L character may
+ be followed by an L, V, LV, or LVT character; an LV or V character may
be followed by a V or T character; an LVT or T character may be follwed
only by a T character.
- 4. Do not end before extending characters or spacing marks. Characters
- with the "mark" property always have the "extend" grapheme breaking
+ 4. Do not end before extending characters or spacing marks. Characters
+ with the "mark" property always have the "extend" grapheme breaking
property.
5. Do not end after prepend characters.
@@ -5190,51 +5461,63 @@ BACKSLASH
PCRE's additional properties
- As well as the standard Unicode properties described above, PCRE sup-
- ports four more that make it possible to convert traditional escape
- sequences such as \w and \s and POSIX character classes to use Unicode
- properties. PCRE uses these non-standard, non-Perl properties inter-
- nally when PCRE_UCP is set. They are:
+ As well as the standard Unicode properties described above, PCRE sup-
+ ports four more that make it possible to convert traditional escape
+ sequences such as \w and \s to use Unicode properties. PCRE uses these
+ non-standard, non-Perl properties internally when PCRE_UCP is set. How-
+ ever, they may also be used explicitly. These properties are:
Xan Any alphanumeric character
Xps Any POSIX space character
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,
- 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.
+ 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; it used to exclude ver-
+ tical tab, for Perl compatibility, but Perl changed, and so PCRE fol-
+ lowed at release 8.34. Xwd matches the same characters as Xan, plus
+ underscore.
+
+ There is another non-standard property, Xuc, which matches any charac-
+ ter that can be represented by a Universal Character Name in C++ and
+ other programming languages. These are the characters $, @, ` (grave
+ accent), and all characters with Unicode code points greater than or
+ equal to U+00A0, except for the surrogates U+D800 to U+DFFF. Note that
+ most base (ASCII) characters are excluded. (Universal Character Names
+ are of the form \uHHHH or \UHHHHHHHH where H is a hexadecimal digit.
+ Note that the Xuc property does not match these sequences but the char-
+ acters that they represent.)
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
@@ -5245,161 +5528,161 @@ BACKSLASH
\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 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.
+ 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.
CIRCUMFLEX AND DOLLAR
- The circumflex and dollar metacharacters are zero-width assertions.
- That is, they test for a particular condition being true without con-
+ The circumflex and dollar metacharacters are zero-width assertions.
+ That is, they test for a particular condition being true without con-
suming any characters from the subject string.
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.)
- The 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). Note, however,
- that it does not actually match the newline. Dollar need not be the
+ The 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). Note, however,
+ that it does not actually match the newline. 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 appears. Dol-
+ but it should be the last item in any branch in which it appears. Dol-
lar 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-
+ 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
- not match CR if it is immediately followed by LF, but otherwise it
- matches all characters (including isolated CRs and LFs). When any Uni-
- code line endings are being recognized, dot does not match CR or LF or
+ 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 if it is immediately followed by LF, but otherwise it
+ matches all characters (including isolated CRs and LFs). When any Uni-
+ code line endings are being recognized, dot does not match CR or LF or
any of the other line ending characters.
- The behaviour of dot with regard to newlines can be changed. If the
- PCRE_DOTALL option is set, a dot matches any one character, without
+ The behaviour of dot with regard to newlines can be changed. If the
+ PCRE_DOTALL option is set, a dot matches any one character, without
exception. If the two-character sequence CRLF is present in the subject
string, it takes two dots to match it.
- The handling of dot is entirely independent of the handling of circum-
- flex and dollar, the only relationship being that they both involve
+ The handling of dot is entirely independent of the handling of circum-
+ flex and dollar, the only relationship being that they both involve
newlines. Dot has no special meaning in a character class.
- 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. Perl also uses
+ 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. Perl also uses
\N to match characters by name; PCRE does not support this.
MATCHING A SINGLE DATA UNIT
- 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; in the
- 32-bit library it is a 32-bit unit. Unlike a dot, \C always matches
- line-ending characters. The feature is provided in Perl in order to
+ 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; in the
+ 32-bit library it is a 32-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 use-
- fully 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
+ fully 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, PCRE_NO_UTF16_CHECK or PCRE_NO_UTF32_CHECK option
+ (and by default it checks this at the start of processing unless the
+ PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK or PCRE_NO_UTF32_CHECK option
is used).
- PCRE does not allow \C to appear in lookbehind assertions (described
- below) in a UTF mode, because this would make it impossible to calcu-
+ PCRE does not allow \C to appear in lookbehind assertions (described
+ 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
+ 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) |
@@ -5407,11 +5690,11 @@ MATCHING A SINGLE DATA UNIT
(?=[\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-
+ 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.
@@ -5421,64 +5704,71 @@ SQUARE BRACKETS AND CHARACTER CLASSES
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 a UTF
- mode, the character may be more than one data unit long. A matched
+ 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
+ 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
+ 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 (UTF-16, UTF-32) mode, characters with values greater than 255
- (0xffff) can be included in a class as a literal string of data units,
+ (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
+ 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
+ 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
- first or last character in the class.
+ 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, or immediately after a range. For
+ example, [b-d-z] matches letters in the range b to d, a hyphen charac-
+ ter, or z.
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.
+ An error is generated if a POSIX character class (see below) or an
+ escape sequence other than one that defines a single character appears
+ at a point where a range ending character is expected. For example,
+ [z-\xff] is valid, but [A-\d] and [A-[:digit:]] are not.
+
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
@@ -5515,15 +5805,16 @@ SQUARE BRACKETS AND CHARACTER CLASSES
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.
+ when it can be interpreted as introducing a POSIX class name, or for a
+ special compatibility feature - see the next two sections), 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:]%]
@@ -5541,15 +5832,18 @@ POSIX CHARACTER CLASSES
lower lower case letters
print printing characters, including space
punct printing characters, excluding letters and digits and space
- space white space (not quite the same as \s)
+ space white space (the same as \s from PCRE 8.34)
upper upper case letters
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
- 11). This makes "space" different to \s, which does not include VT (for
- Perl compatibility).
+ The default "space" characters are HT (9), LF (10), VT (11), FF (12),
+ CR (13), and space (32). If locale-specific matching is taking place,
+ the list of space characters may be different; there may be fewer or
+ more of them. "Space" used to be different to \s, which did not include
+ VT, for Perl compatibility. However, Perl changed at release 5.18, and
+ PCRE followed at release 8.34. "Space" and \s now match the same set
+ of characters.
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
@@ -5561,11 +5855,11 @@ POSIX CHARACTER CLASSES
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 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:
+ By default, 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 certain
+ POSIX classes by other sequences, as follows:
[:alnum:] becomes \p{Xan}
[:alpha:] becomes \p{L}
@@ -5576,9 +5870,48 @@ POSIX CHARACTER CLASSES
[:upper:] becomes \p{Lu}
[:word:] becomes \p{Xwd}
- 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.
+ Negated versions, such as [:^alpha:] use \P instead of \p. Three other
+ POSIX classes are handled specially in UCP mode:
+
+ [:graph:] This matches characters that have glyphs that mark the page
+ when printed. In Unicode property terms, it matches all char-
+ acters with the L, M, N, P, S, or Cf properties, except for:
+
+ U+061C Arabic Letter Mark
+ U+180E Mongolian Vowel Separator
+ U+2066 - U+2069 Various "isolate"s
+
+
+ [:print:] This matches the same characters as [:graph:] plus space
+ characters that are not controls, that is, characters with
+ the Zs property.
+
+ [:punct:] This matches all characters that have the Unicode P (punctua-
+ tion) property, plus those characters whose code points are
+ less than 128 that have the S (Symbol) property.
+
+ The other POSIX classes are unchanged, and match only characters with
+ code points less than 128.
+
+
+COMPATIBILITY FEATURE FOR WORD BOUNDARIES
+
+ In the POSIX.2 compliant library that was included in 4.4BSD Unix, the
+ ugly syntax [[:<:]] and [[:>:]] is used for matching "start of word"
+ and "end of word". PCRE treats these items as follows:
+
+ [[:<:]] is converted to \b(?=\w)
+ [[:>:]] is converted to \b(?<=\w)
+
+ Only these exact character sequences are recognized. A sequence such as
+ [a[:<:]b] provokes error for an unrecognized POSIX class name. This
+ support is not compatible with Perl. It is provided to help migrations
+ from other environments, and is best not used in any new patterns. Note
+ that \b matches at the start and the end of a word (see "Simple asser-
+ tions" above), and in a Perl-style pattern the preceding or following
+ character normally shows which is wanted, without the need for the
+ assertions that are used above in order to give exactly the POSIX be-
+ haviour.
VERTICAL BAR
@@ -5653,7 +5986,9 @@ INTERNAL OPTION SETTING
(*UCP) leading sequences that can be used to set UTF and Unicode prop-
erty modes; they are equivalent to setting the PCRE_UTF8, PCRE_UTF16,
PCRE_UTF32 and the PCRE_UCP options, respectively. The (*UTF) sequence
- is a generic version that can be used with any of the libraries.
+ is a generic version that can be used with any of the libraries. How-
+ ever, the application can set the PCRE_NEVER_UTF option, which locks
+ out the use of the (*UTF) sequences.
SUBPATTERNS
@@ -5773,12 +6108,12 @@ NAMED SUBPATTERNS
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
- 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.
+ Names consist of up to 32 alphanumeric characters and underscores, but
+ must start with a non-digit. 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
to relax this constraint by setting the PCRE_DUPNAMES option at compile
@@ -5806,28 +6141,38 @@ NAMED SUBPATTERNS
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-
- 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.
- This is the same behaviour as testing by number. For further details of
- the interfaces for handling named subpatterns, see the pcreapi documen-
- tation.
+ elsewhere in the pattern, the subpatterns to which the name refers are
+ checked in the order in which they appear in the overall pattern. The
+ first one that is set is used for the reference. For example, this pat-
+ tern matches both "foofoo" and "barbar" but not "foobar" or "barfoo":
+
+ (?:(?<n>foo)|(?<n>bar))\k<n>
+
+
+ If you make a subroutine call to a non-unique named subpattern, the one
+ that corresponds to the first occurrence 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. This is the same behaviour as testing by number. For further
+ details of the interfaces for handling named subpatterns, see the
+ pcreapi documentation.
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
- PCRE_DUPNAMES is not set.
+ ent names are given to subpatterns with the same number. However, you
+ can always 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
@@ -5841,17 +6186,17 @@ REPETITION
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,}
@@ -5860,50 +6205,50 @@ REPETITION
\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 modes, quantifiers apply to characters rather than to individual
- data units. Thus, for example, \x{100}{2} matches two characters, each
+ 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 grapheme clusters, each of
- which may be several data units long (and they may be of different
+ larly, \X{3} matches three Unicode extended grapheme clusters, 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-
- ful for subpatterns that are referenced as subroutines from elsewhere
+ ful for subpatterns that are referenced as subroutines from elsewhere
in the pattern (but see also the section entitled "Defining subpatterns
- for use by reference only" below). Items other than subpatterns that
+ for use by reference only" below). Items other than subpatterns that
have a {0} quantifier are omitted from the compiled pattern.
- For convenience, the three most common quantifiers have single-charac-
+ For convenience, the three most common quantifiers have single-charac-
ter abbreviations:
* is equivalent to {0,}
+ is equivalent to {1,}
? is equivalent to {0,1}
- It is possible to construct infinite loops by following a subpattern
+ It is possible to construct infinite loops by following a subpattern
that can match no characters with a quantifier that has no upper limit,
for example:
(a?)*
Earlier versions of Perl and PCRE used to give an error at compile time
- for such patterns. However, because there are cases where this can be
- useful, such patterns are now accepted, but if any repetition of the
- subpattern does in fact match no characters, the loop is forcibly bro-
+ for such patterns. However, because there are cases where this can be
+ useful, such patterns are now accepted, but if any repetition of the
+ subpattern does in fact match no characters, the loop is forcibly bro-
ken.
- By default, the quantifiers are "greedy", that is, they match as much
- as possible (up to the maximum number of permitted times), without
- causing the rest of the pattern to fail. The classic example of where
+ By default, the quantifiers are "greedy", that is, they match as much
+ as possible (up to the maximum number of permitted times), without
+ causing the rest of the pattern to fail. The classic example of where
this gives problems is in trying to match comments in C programs. These
- appear between /* and */ and within the comment, individual * and /
- characters may appear. An attempt to match C comments by applying the
+ appear between /* and */ and within the comment, individual * and /
+ characters may appear. An attempt to match C comments by applying the
pattern
/\*.*\*/
@@ -5912,19 +6257,19 @@ REPETITION
/* first comment */ not comment /* second comment */
- fails, because it matches the entire string owing to the greediness of
+ fails, because it matches the entire string owing to the greediness of
the .* item.
- However, if a quantifier is followed by a question mark, it ceases to
+ However, if a quantifier is followed by a question mark, it ceases to
be greedy, and instead matches the minimum number of times possible, so
the pattern
/\*.*?\*/
- does the right thing with the C comments. The meaning of the various
- quantifiers is not otherwise changed, just the preferred number of
- matches. Do not confuse this use of question mark with its use as a
- quantifier in its own right. Because it has two uses, it can sometimes
+ does the right thing with the C comments. The meaning of the various
+ quantifiers is not otherwise changed, just the preferred number of
+ matches. Do not confuse this use of question mark with its use as a
+ quantifier in its own right. Because it has two uses, it can sometimes
appear doubled, as in
\d??\d
@@ -5932,45 +6277,45 @@ REPETITION
which matches one digit by preference, but can match two if that is the
only way the rest of the pattern matches.
- If the PCRE_UNGREEDY option is set (an option that is not available in
- Perl), the quantifiers are not greedy by default, but individual ones
- can be made greedy by following them with a question mark. In other
+ If the PCRE_UNGREEDY option is set (an option that is not available in
+ Perl), the quantifiers are not greedy by default, but individual ones
+ can be made greedy by following them with a question mark. In other
words, it inverts the default behaviour.
- When a parenthesized subpattern is quantified with a minimum repeat
- count that is greater than 1 or with a limited maximum, more memory is
- required for the compiled pattern, in proportion to the size of the
+ When a parenthesized subpattern is quantified with a minimum repeat
+ count that is greater than 1 or with a limited maximum, more memory is
+ required for the compiled pattern, in proportion to the size of the
minimum or maximum.
If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equiv-
- alent to Perl's /s) is set, thus allowing the dot to match newlines,
- the pattern is implicitly anchored, because whatever follows will be
- tried against every character position in the subject string, so there
- is no point in retrying the overall match at any position after the
- first. PCRE normally treats such a pattern as though it were preceded
+ alent to Perl's /s) is set, thus allowing the dot to match newlines,
+ the pattern is implicitly anchored, because whatever follows will be
+ tried against every character position in the subject string, so there
+ is no point in retrying the overall match at any position after the
+ first. PCRE normally treats such a pattern as though it were preceded
by \A.
- In cases where it is known that the subject string contains no new-
- lines, it is worth setting PCRE_DOTALL in order to obtain this opti-
+ In cases where it is known that the subject string contains no new-
+ lines, it is worth setting PCRE_DOTALL in order to obtain this opti-
mization, or alternatively using ^ to indicate anchoring explicitly.
- However, there are some cases where the optimization cannot be used.
+ However, there are some cases where the optimization cannot be used.
When .* is inside capturing parentheses that are the subject of a back
reference elsewhere in the pattern, a match at the start may fail where
a later one succeeds. Consider, for example:
(.*)abc\1
- If the subject is "xyz123abc123" the match point is the fourth charac-
+ If the subject is "xyz123abc123" the match point is the fourth charac-
ter. For this reason, such a pattern is not implicitly anchored.
- Another case where implicit anchoring is not applied is when the lead-
- ing .* is inside an atomic group. Once again, a match at the start may
+ Another case where implicit anchoring is not applied is when the lead-
+ ing .* is inside an atomic group. Once again, a match at the start may
fail where a later one succeeds. Consider this pattern:
(?>.*?a)b
- It matches "ab" in the subject "aab". The use of the backtracking con-
+ It matches "ab" in the subject "aab". The use of the backtracking con-
trol verbs (*PRUNE) and (*SKIP) also disable this optimization.
When a capturing subpattern is repeated, the value captured is the sub-
@@ -5979,8 +6324,8 @@ REPETITION
(tweedle[dume]{3}\s*)+
has matched "tweedledum tweedledee" the value of the captured substring
- is "tweedledee". However, if there are nested capturing subpatterns,
- the corresponding captured values may have been set in previous itera-
+ is "tweedledee". However, if there are nested capturing subpatterns,
+ the corresponding captured values may have been set in previous itera-
tions. For example, after
/(a|(b))+/
@@ -5990,53 +6335,53 @@ REPETITION
ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
- With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy")
- repetition, failure of what follows normally causes the repeated item
- to be re-evaluated to see if a different number of repeats allows the
- rest of the pattern to match. Sometimes it is useful to prevent this,
- either to change the nature of the match, or to cause it fail earlier
- than it otherwise might, when the author of the pattern knows there is
+ With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy")
+ repetition, failure of what follows normally causes the repeated item
+ to be re-evaluated to see if a different number of repeats allows the
+ rest of the pattern to match. Sometimes it is useful to prevent this,
+ either to change the nature of the match, or to cause it fail earlier
+ than it otherwise might, when the author of the pattern knows there is
no point in carrying on.
- Consider, for example, the pattern \d+foo when applied to the subject
+ Consider, for example, the pattern \d+foo when applied to the subject
line
123456bar
After matching all 6 digits and then failing to match "foo", the normal
- action of the matcher is to try again with only 5 digits matching the
- \d+ item, and then with 4, and so on, before ultimately failing.
- "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides
- the means for specifying that once a subpattern has matched, it is not
+ action of the matcher is to try again with only 5 digits matching the
+ \d+ item, and then with 4, and so on, before ultimately failing.
+ "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides
+ the means for specifying that once a subpattern has matched, it is not
to be re-evaluated in this way.
- If we use atomic grouping for the previous example, the matcher gives
- up immediately on failing to match "foo" the first time. The notation
+ If we use atomic grouping for the previous example, the matcher gives
+ up immediately on failing to match "foo" the first time. The notation
is a kind of special parenthesis, starting with (?> as in this example:
(?>\d+)foo
- This kind of parenthesis "locks up" the part of the pattern it con-
- tains once it has matched, and a failure further into the pattern is
- prevented from backtracking into it. Backtracking past it to previous
+ This kind of parenthesis "locks up" the part of the pattern it con-
+ tains once it has matched, and a failure further into the pattern is
+ prevented from backtracking into it. Backtracking past it to previous
items, however, works as normal.
- An alternative description is that a subpattern of this type matches
- the string of characters that an identical standalone pattern would
+ An alternative description is that a subpattern of this type matches
+ the string of characters that an identical standalone pattern would
match, if anchored at the current point in the subject string.
Atomic grouping subpatterns are not capturing subpatterns. Simple cases
such as the above example can be thought of as a maximizing repeat that
- must swallow everything it can. So, while both \d+ and \d+? are pre-
- pared to adjust the number of digits they match in order to make the
+ must swallow everything it can. So, while both \d+ and \d+? are pre-
+ pared to adjust the number of digits they match in order to make the
rest of the pattern match, (?>\d+) can only match an entire sequence of
digits.
- Atomic groups in general can of course contain arbitrarily complicated
- subpatterns, and can be nested. However, when the subpattern for an
+ Atomic groups in general can of course contain arbitrarily complicated
+ subpatterns, and can be nested. However, when the subpattern for an
atomic group is just a single repeated item, as in the example above, a
- simpler notation, called a "possessive quantifier" can be used. This
- consists of an additional + character following a quantifier. Using
+ simpler notation, called a "possessive quantifier" can be used. This
+ consists of an additional + character following a quantifier. Using
this notation, the previous example can be rewritten as
\d++foo
@@ -6046,45 +6391,45 @@ ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
(abc|xyz){2,3}+
- Possessive quantifiers are always greedy; the setting of the
+ Possessive quantifiers are always greedy; the setting of the
PCRE_UNGREEDY option is ignored. They are a convenient notation for the
- simpler forms of atomic group. However, there is no difference in the
- meaning of a possessive quantifier and the equivalent atomic group,
- though there may be a performance difference; possessive quantifiers
+ simpler forms of atomic group. However, there is no difference in the
+ meaning of a possessive quantifier and the equivalent atomic group,
+ though there may be a performance difference; possessive quantifiers
should be slightly faster.
- The possessive quantifier syntax is an extension to the Perl 5.8 syn-
- tax. Jeffrey Friedl originated the idea (and the name) in the first
+ The possessive quantifier syntax is an extension to the Perl 5.8 syn-
+ tax. Jeffrey Friedl originated the idea (and the name) in the first
edition of his book. Mike McCloskey liked it, so implemented it when he
- built Sun's Java package, and PCRE copied it from there. It ultimately
+ built Sun's Java package, and PCRE copied it from there. It ultimately
found its way into Perl at release 5.10.
PCRE has an optimization that automatically "possessifies" certain sim-
- ple pattern constructs. For example, the sequence A+B is treated as
- A++B because there is no point in backtracking into a sequence of A's
+ ple pattern constructs. For example, the sequence A+B is treated as
+ A++B because there is no point in backtracking into a sequence of A's
when B must follow.
- When a pattern contains an unlimited repeat inside a subpattern that
- can itself be repeated an unlimited number of times, the use of an
- atomic group is the only way to avoid some failing matches taking a
+ When a pattern contains an unlimited repeat inside a subpattern that
+ can itself be repeated an unlimited number of times, the use of an
+ atomic group is the only way to avoid some failing matches taking a
very long time indeed. The pattern
(\D+|<\d+>)*[!?]
- matches an unlimited number of substrings that either consist of non-
- digits, or digits enclosed in <>, followed by either ! or ?. When it
+ matches an unlimited number of substrings that either consist of non-
+ digits, or digits enclosed in <>, followed by either ! or ?. When it
matches, it runs quickly. However, if it is applied to
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- it takes a long time before reporting failure. This is because the
- string can be divided between the internal \D+ repeat and the external
- * repeat in a large number of ways, and all have to be tried. (The
- example uses [!?] rather than a single character at the end, because
- both PCRE and Perl have an optimization that allows for fast failure
- when a single character is used. They remember the last single charac-
- ter that is required for a match, and fail early if it is not present
- in the string.) If the pattern is changed so that it uses an atomic
+ it takes a long time before reporting failure. This is because the
+ string can be divided between the internal \D+ repeat and the external
+ * repeat in a large number of ways, and all have to be tried. (The
+ example uses [!?] rather than a single character at the end, because
+ both PCRE and Perl have an optimization that allows for fast failure
+ when a single character is used. They remember the last single charac-
+ ter that is required for a match, and fail early if it is not present
+ in the string.) If the pattern is changed so that it uses an atomic
group, like this:
((?>\D+)|<\d+>)*[!?]
@@ -6096,28 +6441,28 @@ BACK REFERENCES
Outside a character class, a backslash followed by a digit greater than
0 (and possibly further digits) is a back reference to a capturing sub-
- pattern earlier (that is, to its left) in the pattern, provided there
+ pattern earlier (that is, to its left) in the pattern, provided there
have been that many previous capturing left parentheses.
However, if the decimal number following the backslash is less than 10,
- it is always taken as a back reference, and causes an error only if
- there are not that many capturing left parentheses in the entire pat-
- tern. In other words, the parentheses that are referenced need not be
- to the left of the reference for numbers less than 10. A "forward back
- reference" of this type can make sense when a repetition is involved
- and the subpattern to the right has participated in an earlier itera-
+ it is always taken as a back reference, and causes an error only if
+ there are not that many capturing left parentheses in the entire pat-
+ tern. In other words, the parentheses that are referenced need not be
+ to the left of the reference for numbers less than 10. A "forward back
+ reference" of this type can make sense when a repetition is involved
+ and the subpattern to the right has participated in an earlier itera-
tion.
- It is not possible to have a numerical "forward back reference" to a
- subpattern whose number is 10 or more using this syntax because a
- sequence such as \50 is interpreted as a character defined in octal.
+ It is not possible to have a numerical "forward back reference" to a
+ subpattern whose number is 10 or more using this syntax because a
+ sequence such as \50 is interpreted as a character defined in octal.
See the subsection entitled "Non-printing characters" above for further
- details of the handling of digits following a backslash. There is no
- such problem when named parentheses are used. A back reference to any
+ details of the handling of digits following a backslash. There is no
+ such problem when named parentheses are used. A back reference to any
subpattern is possible using named parentheses (see below).
- Another way of avoiding the ambiguity inherent in the use of digits
- following a backslash is to use the \g escape sequence. This escape
+ Another way of avoiding the ambiguity inherent in the use of digits
+ following a backslash is to use the \g escape sequence. This escape
must be followed by an unsigned number or a negative number, optionally
enclosed in braces. These examples are all identical:
@@ -6125,7 +6470,7 @@ BACK REFERENCES
(ring), \g1
(ring), \g{1}
- An unsigned number specifies an absolute reference without the ambigu-
+ An unsigned number specifies an absolute reference without the ambigu-
ity that is present in the older syntax. It is also useful when literal
digits follow the reference. A negative number is a relative reference.
Consider this example:
@@ -6134,33 +6479,33 @@ BACK REFERENCES
The sequence \g{-1} is a reference to the most recently started captur-
ing subpattern before \g, that is, is it equivalent to \2 in this exam-
- ple. Similarly, \g{-2} would be equivalent to \1. The use of relative
- references can be helpful in long patterns, and also in patterns that
- are created by joining together fragments that contain references
+ ple. Similarly, \g{-2} would be equivalent to \1. The use of relative
+ references can be helpful in long patterns, and also in patterns that
+ are created by joining together fragments that contain references
within themselves.
- A back reference matches whatever actually matched the capturing sub-
- pattern in the current subject string, rather than anything matching
+ A back reference matches whatever actually matched the capturing sub-
+ pattern in the current subject string, rather than anything matching
the subpattern itself (see "Subpatterns as subroutines" below for a way
of doing that). So the pattern
(sens|respons)e and \1ibility
- matches "sense and sensibility" and "response and responsibility", but
- not "sense and responsibility". If caseful matching is in force at the
- time of the back reference, the case of letters is relevant. For exam-
+ matches "sense and sensibility" and "response and responsibility", but
+ not "sense and responsibility". If caseful matching is in force at the
+ time of the back reference, the case of letters is relevant. For exam-
ple,
((?i)rah)\s+\1
- matches "rah rah" and "RAH RAH", but not "RAH rah", even though the
+ matches "rah rah" and "RAH RAH", but not "RAH rah", even though the
original capturing subpattern is matched caselessly.
- There are several different ways of writing back references to named
- subpatterns. The .NET syntax \k{name} and the Perl syntax \k<name> or
- \k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's
+ There are several different ways of writing back references to named
+ subpatterns. The .NET syntax \k{name} and the Perl syntax \k<name> or
+ \k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's
unified back reference syntax, in which \g can be used for both numeric
- and named references, is also supported. We could rewrite the above
+ and named references, is also supported. We could rewrite the above
example in any of the following ways:
(?<p1>(?i)rah)\s+\k<p1>
@@ -6168,66 +6513,67 @@ BACK REFERENCES
(?P<p1>(?i)rah)\s+(?P=p1)
(?<p1>(?i)rah)\s+\g{p1}
- A subpattern that is referenced by name may appear in the pattern
+ A subpattern that is referenced by name may appear in the pattern
before or after the reference.
- There may be more than one back reference to the same subpattern. If a
- subpattern has not actually been used in a particular match, any back
+ There may be more than one back reference to the same subpattern. If a
+ subpattern has not actually been used in a particular match, any back
references to it always fail by default. For example, the pattern
(a|(bc))\2
- always fails if it starts to match "a" rather than "bc". However, if
+ always fails if it starts to match "a" rather than "bc". However, if
the PCRE_JAVASCRIPT_COMPAT option is set at compile time, a back refer-
ence to an unset value matches an empty string.
- Because there may be many capturing parentheses in a pattern, all dig-
- 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 white space. Otherwise, the
+ Because there may be many capturing parentheses in a pattern, all dig-
+ 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 white space. Otherwise, the
\g{ syntax or an empty comment (see "Comments" below) can be used.
Recursive back references
- A back reference that occurs inside the parentheses to which it refers
- fails when the subpattern is first used, so, for example, (a\1) never
- matches. However, such references can be useful inside repeated sub-
+ A back reference that occurs inside the parentheses to which it refers
+ fails when the subpattern is first used, so, for example, (a\1) never
+ matches. However, such references can be useful inside repeated sub-
patterns. For example, the pattern
(a|b\1)+
matches any number of "a"s and also "aba", "ababbaa" etc. At each iter-
- ation of the subpattern, the back reference matches the character
- string corresponding to the previous iteration. In order for this to
- work, the pattern must be such that the first iteration does not need
- to match the back reference. This can be done using alternation, as in
+ ation of the subpattern, the back reference matches the character
+ string corresponding to the previous iteration. In order for this to
+ work, the pattern must be such that the first iteration does not need
+ to match the back reference. This can be done using alternation, as in
the example above, or by a quantifier with a minimum of zero.
- Back references of this type cause the group that they reference to be
- treated as an atomic group. Once the whole group has been matched, a
- subsequent matching failure cannot cause backtracking into the middle
+ Back references of this type cause the group that they reference to be
+ treated as an atomic group. Once the whole group has been matched, a
+ subsequent matching failure cannot cause backtracking into the middle
of the group.
ASSERTIONS
- An assertion is a test on the characters following or preceding the
- current matching point that does not actually consume any characters.
- The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are
+ An assertion is a test on the characters following or preceding the
+ current matching point that does not actually consume any characters.
+ The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are
described above.
- More complicated assertions are coded as subpatterns. There are two
- kinds: those that look ahead of the current position in the subject
- string, and those that look behind it. An assertion subpattern is
- matched in the normal way, except that it does not cause the current
+ More complicated assertions are coded as subpatterns. There are two
+ kinds: those that look ahead of the current position in the subject
+ string, and those 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.
- 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.
+ 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. (Perl sometimes, but not always, does do capturing in nega-
+ tive assertions.)
For compatibility with Perl, assertion subpatterns may be repeated;
though it makes no sense to assert the same thing several times, the
@@ -6456,25 +6802,20 @@ CONDITIONAL SUBPATTERNS
Perl uses the syntax (?(<name>)...) 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.
+ also recognized.
Rewriting the above example to use a named subpattern gives this:
(?<OPEN> \( )? [^()]+ (?(<OPEN>) \) )
- 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:
@@ -6482,51 +6823,51 @@ CONDITIONAL SUBPATTERNS
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 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"
+ 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) (?<byte> 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
\b (?&byte) (\.(?&byte)){3} \b
- The first part of the pattern is a DEFINE group inside which a another
- group named "byte" is defined. This matches an individual component of
- an IPv4 address (a number less than 256). When matching takes place,
- this part of the pattern is skipped because DEFINE acts like a false
- condition. The rest of the pattern uses references to the named group
- to match the four dot-separated components of an IPv4 address, insist-
+ The first part of the pattern is a DEFINE group inside which a another
+ group named "byte" is defined. This matches an individual component of
+ an IPv4 address (a number less than 256). When matching takes place,
+ this part of the pattern is skipped because DEFINE acts like a false
+ condition. The rest of the pattern uses references to the named group
+ to match the four dot-separated components of an IPv4 address, insist-
ing on a word boundary at each end.
Assertion conditions
- If the condition is not in any of the above formats, it must be an
- assertion. This may be a positive or negative lookahead or lookbehind
- assertion. Consider this pattern, again containing non-significant
+ If the condition is not in any of the above formats, it must be an
+ assertion. This may be a positive or negative lookahead or lookbehind
+ assertion. Consider this pattern, again containing non-significant
white space, and with the two alternatives on the second line:
(?(?=[^a-z]*[a-z])
\d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )
- The condition is a positive lookahead assertion that matches an
- optional sequence of non-letters followed by a letter. In other words,
- it tests for the presence of at least one letter in the subject. If a
- letter is found, the subject is matched against the first alternative;
- otherwise it is matched against the second. This pattern matches
- strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are
+ The condition is a positive lookahead assertion that matches an
+ optional sequence of non-letters followed by a letter. In other words,
+ it tests for the presence of at least one letter in the subject. If a
+ letter is found, the subject is matched against the first alternative;
+ otherwise it is matched against the second. This pattern matches
+ strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are
letters and dd are digits.
@@ -6535,41 +6876,41 @@ COMMENTS
There are two ways of including comments in patterns that are processed
by PCRE. In both cases, the start of the comment must not be in a char-
acter class, nor in the middle of any other sequence of related charac-
- ters such as (?: or a subpattern name or number. The characters that
+ ters such as (?: or a subpattern name or number. The characters that
make up a comment play no part in the pattern matching.
- The sequence (?# marks the start of a comment that continues up to the
- next closing parenthesis. Nested parentheses are not permitted. If the
+ The sequence (?# marks the start of a comment that continues up to the
+ next closing parenthesis. Nested parentheses are not permitted. If the
PCRE_EXTENDED 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 charac-
+ 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
- a compiling function or by a special sequence at the start of the pat-
+ 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
+ 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
- On encountering the # character, pcre_compile() skips along, looking
- for a newline in the pattern. The sequence \n is still literal at this
- stage, so it does not terminate the comment. Only an actual character
+ On encountering the # character, pcre_compile() skips along, looking
+ for a newline in the pattern. The sequence \n is still literal at this
+ stage, so it does not terminate the comment. Only an actual character
with the code value 0x0a (the default newline) does so.
RECURSIVE PATTERNS
- Consider the problem of matching a string in parentheses, allowing for
- unlimited nested parentheses. Without the use of recursion, the best
- that can be done is to use a pattern that matches up to some fixed
- depth of nesting. It is not possible to handle an arbitrary nesting
+ Consider the problem of matching a string in parentheses, allowing for
+ unlimited nested parentheses. Without the use of recursion, the best
+ that can be done is to use a pattern that matches up to some fixed
+ depth of nesting. It is not possible to handle an arbitrary nesting
depth.
For some time, Perl has provided a facility that allows regular expres-
- sions to recurse (amongst other things). It does this by interpolating
- Perl code in the expression at run time, and the code can refer to the
+ sions to recurse (amongst other things). It does this by interpolating
+ Perl code in the expression at run time, and the code can refer to the
expression itself. A Perl pattern using code interpolation to solve the
parentheses problem can be created like this:
@@ -6579,201 +6920,201 @@ RECURSIVE PATTERNS
refers recursively to the pattern in which it appears.
Obviously, PCRE cannot support the interpolation of Perl code. Instead,
- it supports special syntax for recursion of the entire pattern, and
- also for individual subpattern recursion. After its introduction in
- PCRE and Python, this kind of recursion was subsequently introduced
+ it supports special syntax for recursion of the entire pattern, and
+ also for individual subpattern recursion. After its introduction in
+ PCRE and Python, this kind of recursion was subsequently introduced
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 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
+ A special item that consists of (? followed by a number greater than
+ 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
+ This PCRE pattern solves the nested parentheses problem (assume the
PCRE_EXTENDED option is set so that white space is ignored):
\( ( [^()]++ | (?R) )* \)
- First it matches an opening parenthesis. Then it matches any number of
- substrings which can either be a sequence of non-parentheses, or a
- recursive match of the pattern itself (that is, a correctly parenthe-
+ First it matches an opening parenthesis. Then it matches any number of
+ substrings which can either be a sequence of non-parentheses, or a
+ recursive match of the pattern itself (that is, a correctly parenthe-
sized substring). Finally there is a closing parenthesis. Note the use
of a possessive quantifier to avoid backtracking into sequences of non-
parentheses.
- If this were part of a larger pattern, you would not want to recurse
+ If this were part of a larger pattern, you would not want to recurse
the entire pattern, so instead you could use this:
( \( ( [^()]++ | (?1) )* \) )
- We have put the pattern into parentheses, and caused the recursion to
+ We have put the pattern into parentheses, and caused the recursion to
refer to them instead of the whole pattern.
- In a larger pattern, keeping track of parenthesis numbers can be
- tricky. This is made easier by the use of relative references. Instead
+ In a larger pattern, keeping track of parenthesis numbers can be
+ tricky. This is made easier by the use of relative references. Instead
of (?1) in the pattern above you can write (?-2) to refer to the second
- most recently opened parentheses preceding the recursion. In other
- words, a negative number counts capturing parentheses leftwards from
+ most recently opened parentheses preceding the recursion. In other
+ words, a negative number counts capturing parentheses leftwards from
the point at which it is encountered.
- 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 non-recursive subroutine calls, as described in
+ 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 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
+ An alternative approach is to use named parentheses instead. The Perl
+ syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also
supported. We could rewrite the above example as follows:
(?<pn> \( ( [^()]++ | (?&pn) )* \) )
- If there is more than one subpattern with the same name, the earliest
+ If there is more than one subpattern with the same name, the earliest
one is used.
- This particular example pattern that we have been looking at contains
+ This particular example pattern that we have been looking at contains
nested unlimited repeats, and so the use of a possessive quantifier for
matching strings of non-parentheses is important when applying the pat-
- tern to strings that do not match. For example, when this pattern is
+ tern to strings that do not match. For example, when this pattern is
applied to
(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
- it yields "no match" quickly. However, if a possessive quantifier is
- not used, the match runs for a very long time indeed because there are
- so many different ways the + and * repeats can carve up the subject,
+ it yields "no match" quickly. However, if a possessive quantifier is
+ not used, the match runs for a very long time indeed because there are
+ so many different ways the + and * repeats can carve up the subject,
and all have to be tested before failure can be reported.
- At the end of a match, the values of capturing parentheses are those
- from the outermost level. If you want to obtain intermediate values, a
- callout function can be used (see below and the pcrecallout documenta-
+ At the end of a match, the values of capturing parentheses are those
+ from the outermost level. If you want to obtain intermediate values, a
+ callout function can be used (see below and the pcrecallout documenta-
tion). If the pattern above is matched against
(ab(cd)ef)
- 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 captured value is
- unset, even if it was (temporarily) set at a deeper level during the
+ 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 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.
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
+ 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 palin-
- dromic string that contains an odd number of characters (for example,
+ alternatives and there is a subsequent matching failure. This can be
+ illustrated by the following pattern, which purports to match a palin-
+ dromic string that contains an odd number of characters (for example,
"a", "aba", "abcba", "abcdcba"):
^(.|(.)(?1)\2)$
The idea is that it either matches a single character, or two identical
- characters surrounding a sub-palindrome. In Perl, this pattern works;
- in PCRE it does not if the pattern is longer than three characters.
+ characters surrounding a sub-palindrome. In Perl, this pattern works;
+ in PCRE it does not if the pattern is longer than three characters.
Consider the subject string "abcba":
- At the top level, the first character is matched, but as it is not at
+ At the top level, the first character is matched, but as it is not at
the end of the string, the first alternative fails; the second alterna-
tive is taken and the recursion kicks in. The recursive call to subpat-
- tern 1 successfully matches the next character ("b"). (Note that the
+ tern 1 successfully matches the next character ("b"). (Note that the
beginning and end of line tests are not part of the recursion).
- Back at the top level, the next character ("c") is compared with what
- subpattern 2 matched, which was "a". This fails. Because the recursion
- is treated as an atomic group, there are now no backtracking points,
- and so the entire match fails. (Perl is able, at this point, to re-
- enter the recursion and try the second alternative.) However, if the
+ Back at the top level, the next character ("c") is compared with what
+ subpattern 2 matched, which was "a". This fails. Because the recursion
+ is treated as an atomic group, there are now no backtracking points,
+ and so the entire match fails. (Perl is able, at this point, to re-
+ enter the recursion and try the second alternative.) However, if the
pattern is written with the alternatives in the other order, things are
different:
^((.)(?1)\2|.)$
- This time, the recursing alternative is tried first, and continues to
- recurse until it runs out of characters, at which point the recursion
- fails. But this time we do have another alternative to try at the
- higher level. That is the big difference: in the previous case the
+ This time, the recursing alternative is tried first, and continues to
+ recurse until it runs out of characters, at which point the recursion
+ fails. But this time we do have another alternative to try at the
+ higher level. That is the big difference: in the previous case the
remaining alternative is at a deeper recursion level, which PCRE cannot
use.
- To change the pattern so that it matches all palindromic strings, not
- just those with an odd number of characters, it is tempting to change
+ To change the pattern so that it matches all palindromic strings, not
+ just those with an odd number of characters, it is tempting to change
the pattern to this:
^((.)(?1)\2|.?)$
- Again, this works in Perl, but not in PCRE, and for the same reason.
- When a deeper recursion has matched a single character, it cannot be
- entered again in order to match an empty string. The solution is to
- separate the two cases, and write out the odd and even cases as alter-
+ Again, this works in Perl, but not in PCRE, and for the same reason.
+ When a deeper recursion has matched a single character, it cannot be
+ entered again in order to match an empty string. The solution is to
+ separate the two cases, and write out the odd and even cases as alter-
natives at the higher level:
^(?:((.)(?1)\2|)|((.)(?3)\4|.))
- If you want to match typical palindromic phrases, the pattern has to
+ If you want to match typical palindromic phrases, the pattern has to
ignore all non-word characters, which can be done like this:
^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$
If run with the PCRE_CASELESS option, this pattern matches phrases such
as "A man, a plan, a canal: Panama!" and it works well in both PCRE and
- Perl. Note the use of the possessive quantifier *+ to avoid backtrack-
- ing into sequences of non-word characters. Without this, PCRE takes a
- great deal longer (ten times or more) to match typical phrases, and
+ Perl. Note the use of the possessive quantifier *+ to avoid backtrack-
+ ing into sequences of non-word characters. Without this, PCRE takes a
+ great deal longer (ten times or more) to match typical phrases, and
Perl takes so long that you think it has gone into a loop.
- WARNING: The palindrome-matching patterns above work only if the sub-
- ject string does not start with a palindrome that is shorter than the
- entire string. For example, although "abcba" is correctly matched, if
- the subject is "ababa", 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 alter-
+ WARNING: The palindrome-matching patterns above work only if the sub-
+ ject string does not start with a palindrome that is shorter than the
+ entire string. For example, although "abcba" is correctly matched, if
+ the subject is "ababa", 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 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
+ 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
+ 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 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
+ 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)...
@@ -6784,190 +7125,203 @@ SUBPATTERNS AS SUBROUTINES
(sens|respons)e and \1ibility
- matches "sense and sensibility" and "response and responsibility", but
+ matches "sense and sensibility" and "response and responsibility", but
not "sense and responsibility". If instead the pattern
(sens|respons)e and (?1)ibility
- is used, it does match "sense and responsibility" as well as the other
- two strings. Another example is given in the discussion of DEFINE
+ 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.
- All subroutine calls, whether recursive or not, are always treated as
- atomic groups. That is, once a subroutine has matched some of the sub-
+ 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
+ natives and there is a subsequent matching failure. Any capturing
+ parentheses that are set during the subroutine call revert to their
previous values afterwards.
- 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
+ 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))
- It matches "abcabc". It does not match "abcABC" because the change of
+ It matches "abcabc". It does not match "abcABC" because the change of
processing option does not affect the called subpattern.
ONIGURUMA SUBROUTINE SYNTAX
- For compatibility with Oniguruma, the non-Perl syntax \g followed by a
+ For compatibility with Oniguruma, the non-Perl syntax \g followed by a
name or a number enclosed either in angle brackets or single quotes, is
- an alternative syntax for referencing a subpattern as a subroutine,
- possibly recursively. Here are two of the examples used above, rewrit-
+ an alternative syntax for referencing a subpattern as a subroutine,
+ possibly recursively. Here are two of the examples used above, rewrit-
ten using this syntax:
(?<pn> \( ( (?>[^()]+) | \g<pn> )* \) )
(sens|respons)e and \g'1'ibility
- PCRE supports an extension to Oniguruma: if a number is preceded by a
+ PCRE supports an extension to Oniguruma: if a number is preceded by a
plus or a minus sign it is taken as a relative reference. For example:
(abc)(?i:\g<-1>)
- Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not
- synonymous. The former is a back reference; the latter is a subroutine
+ Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not
+ synonymous. The former is a back reference; the latter is a subroutine
call.
CALLOUTS
Perl has a feature whereby using the sequence (?{...}) causes arbitrary
- Perl code to be obeyed in the middle of matching a regular expression.
+ Perl code to be obeyed in the middle of matching a regular expression.
This makes it possible, amongst other things, to extract different sub-
strings that match the same pair of parentheses when there is a repeti-
tion.
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 (8-bit library) or pcre[16|32]_callout (16-bit or 32-bit
- library). By default, this variable contains NULL, which disables all
+ an external function by putting its entry point in the global variable
+ pcre_callout (8-bit library) or pcre[16|32]_callout (16-bit or 32-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
- callout points, you can put a number less than 256 after the letter C.
- The default value is zero. For example, this pattern has two callout
+ 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 can put 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 flag is passed to a compiling function, call-
- outs are automatically installed before each item in the pattern. They
- are all numbered 255.
+ 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. If there is a conditional group in the pattern
+ whose condition is an assertion, an additional callout is inserted just
+ before the condition. An explicit callout may also be set at this posi-
+ tion, as in this example:
+
+ (?(?C9)(?=a)abc|def)
+
+ Note that this applies only to assertion conditions, not to other types
+ of condition.
- 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.
+ 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.
+
+ By default, PCRE implements a number of optimizations at compile time
+ and matching time, and one side-effect is that sometimes callouts are
+ skipped. If you need all possible callouts to happen, you need to set
+ options that disable the relevant optimizations. More details, and a
+ complete description of the interface to the callout function, are
+ given in the pcrecallout documentation.
BACKTRACKING CONTROL
Perl 5.10 introduced a number of "Special Backtracking Control Verbs",
- which are described in the Perl documentation as "experimental and sub-
- ject to change or removal in a future version of Perl". It goes on to
- say: "Their usage in production code should be noted to avoid problems
- during upgrades." The same remarks apply to the PCRE features described
- 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 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.
+ which are still described in the Perl documentation as "experimental
+ and subject to change or removal in a future version of Perl". It goes
+ on to say: "Their usage in production code should be noted to avoid
+ problems during upgrades." The same remarks apply to the PCRE features
+ described in this section.
- 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-
+ 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. A name is
+ (*VERB) or (*VERB:NAME). Some may take either form, possibly behaving
+ differently depending on whether or not a name 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 and 32-bit library. If the name is empty, that is, if the clos-
- ing 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.
+ 16-bit and 32-bit libraries. 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.
+
+ Since these verbs are specifically related to backtracking, most of
+ them can be used only when the pattern is to be matched using one of
+ the traditional matching functions, because these use a backtracking
+ algorithm. With the exception of (*FAIL), which behaves like a failing
+ negative assertion, the backtracking control verbs cause an error if
+ encountered by a DFA matching function.
+
+ The behaviour of these verbs in repeated groups, assertions, and in
+ subpatterns called as subroutines (whether or not recursively) is docu-
+ mented below.
Optimizations that affect backtracking verbs
- PCRE contains some optimizations that are used to speed up matching by
+ 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 present. When one of these optimizations suppresses
- the running of a match, any included backtracking verbs will not, of
+ may know the minimum length of matching subject, or that a particular
+ character must be present. When one of these optimizations bypasses the
+ running of a match, any 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_com-
+ 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,
+ 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. 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:
+ 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) in triggered in a posi-
+ tive assertion, the assertion succeeds; in a negative assertion, the
+ assertion fails.
+
+ If (*ACCEPT) is inside capturing parentheses, the data so far is cap-
+ tured. 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 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-
+ 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) 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:
+ When a match succeeds, the name of the last-encountered (*MARK:NAME),
+ (*PRUNE:NAME), or (*THEN:NAME) 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 out-
+ putting of (*MARK) data:
re> /X(*MARK:A)Y|X(*MARK:B)Z/K
data> XY
@@ -6982,57 +7336,67 @@ BACKTRACKING CONTROL
efficient way of obtaining this information than putting each alterna-
tive in its own capturing parentheses.
- 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.
+ If a verb with a name is encountered in a positive assertion that is
+ true, the name is recorded and passed back if it is the last-encoun-
+ tered. This does not happen for negative assertions or failing positive
+ assertions.
- 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:
+ After a partial match or a failed match, the last encountered name in
+ the entire match process is returned. For example:
re> /X(*MARK:A)Y|X(*MARK:B)Z/K
data> XP
No match, mark = B
- Note that in this unanchored example the mark is retained from the
+ 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
+ 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
- this localization also applies in subroutine calls and assertions.)
+ 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 or an assertion that is true, its effect
+ is confined to that group, because once the group has been matched,
+ there is never any backtracking into it. In this situation, backtrack-
+ ing can "jump back" to the left of the entire atomic group or asser-
+ tion. (Remember also, as stated above, that this localization also
+ applies in subroutine calls.)
These verbs differ in exactly what kind of failure occurs when back-
- tracking reaches them.
+ tracking reaches them. The behaviour described below is what happens
+ when the verb is not in a subroutine or an assertion. Subsequent sec-
+ tions cover these special cases.
(*COMMIT)
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
- point, or not at all. For example:
+ to fail outright if there is a later matching failure that causes back-
+ tracking to reach it. Even if the pattern is unanchored, no further
+ attempts to find a match by advancing the starting point take place. If
+ (*COMMIT) is the only backtracking verb that is encountered, once it
+ has been passed pcre_exec() is committed to finding a match at the cur-
+ rent 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.
+ If there is more than one backtracking verb in a pattern, a different
+ one that follows (*COMMIT) may be triggered first, so merely passing
+ (*COMMIT) during a match does not always guarantee that a match must be
+ at this starting point.
+
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:
@@ -7052,66 +7416,80 @@ BACKTRACKING CONTROL
(*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
- uses of (*PRUNE) that cannot be expressed in any other way. The behav-
- iour of (*PRUNE:NAME) is the same as (*MARK:NAME)(*PRUNE). In an
- anchored pattern (*PRUNE) has the same effect as (*COMMIT).
+ the subject if there is a later matching failure that causes backtrack-
+ ing to reach it. 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 alternative to an atomic group or possessive quan-
+ tifier, but there are some uses of (*PRUNE) that cannot be expressed in
+ any other way. In an anchored pattern (*PRUNE) has the same effect as
+ (*COMMIT).
+
+ The behaviour of (*PRUNE:NAME) is the not the same as
+ (*MARK:NAME)(*PRUNE). It is like (*MARK:NAME) in that the name is
+ remembered for passing back to the caller. However, (*SKIP:NAME)
+ searches only for names set with (*MARK).
(*SKIP)
- This verb, when given without a name, is like (*PRUNE), except that if
- the pattern is unanchored, the "bumpalong" advance is not to the next
+ This verb, when given without a name, is like (*PRUNE), except that if
+ the pattern is unanchored, the "bumpalong" advance is not to the next
character, but to the position in the subject where (*SKIP) was encoun-
- tered. (*SKIP) signifies that whatever text was matched leading up to
+ tered. (*SKIP) signifies that whatever text was matched leading up to
it cannot be part of a successful match. Consider:
a+(*SKIP)b
- If the subject is "aaaac...", after the first match attempt fails
- (starting at the first character in the string), the starting point
+ If the subject is "aaaac...", after the first match attempt fails
+ (starting at the first character in the string), the starting point
skips on to start the next attempt at "c". Note that a possessive quan-
- tifer does not have the same effect as this example; although it would
- suppress backtracking during the first match attempt, the second
- attempt would start at the second character instead of skipping on to
+ tifer does not have the same effect as this example; although it would
+ suppress backtracking during the first match attempt, the second
+ attempt would start at the second character instead of skipping on to
"c".
(*SKIP:NAME)
- When (*SKIP) has an associated name, its behaviour is modified. If the
- following pattern fails to match, the previous path through the pattern
- 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, the (*SKIP) is ignored.
+ When (*SKIP) has an associated name, its behaviour is modified. When it
+ is triggered, the previous path through the pattern 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 corresponds to that
+ (*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with
+ a matching name is found, the (*SKIP) is ignored.
+
+ Note that (*SKIP:NAME) searches only for names set by (*MARK:NAME). It
+ ignores names that are set by (*PRUNE:NAME) or (*THEN:NAME).
(*THEN) or (*THEN:NAME)
- 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:
+ This verb causes a skip to the next innermost alternative when back-
+ tracking reaches it. That is, it cancels any further backtracking
+ 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
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 (*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 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:
+ into COND1. If that succeeds and BAR fails, COND3 is tried. If subse-
+ quently BAZ fails, there are no more alternatives, so there is a back-
+ track to whatever came before the entire group. If (*THEN) is not
+ inside an alternation, it acts like (*PRUNE).
+
+ The behaviour of (*THEN:NAME) is the not the same as
+ (*MARK:NAME)(*THEN). It is like (*MARK:NAME) in that the name is
+ remembered for passing back to the caller. However, (*SKIP:NAME)
+ searches only for names set with (*MARK).
+
+ 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
@@ -7127,7 +7505,7 @@ BACKTRACKING CONTROL
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
+ Note 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:
@@ -7151,16 +7529,78 @@ BACKTRACKING CONTROL
the advance may be more than one character. (*COMMIT) is the strongest,
causing the entire match to fail.
- 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:
+ More than one backtracking verb
+
+ If more than one backtracking verb is present in a pattern, the one
+ that is backtracked onto first acts. For example, consider this pat-
+ tern, where A, B, etc. are complex pattern fragments:
+
+ (A(*COMMIT)B(*THEN)C|ABD)
+
+ If A matches but B fails, the backtrack to (*COMMIT) causes the entire
+ match to fail. However, if A and B match, but C fails, the backtrack to
+ (*THEN) causes the next alternative (ABD) to be tried. This behaviour
+ is consistent, but is not always the same as Perl's. It means that if
+ two or more backtracking verbs appear in succession, all the the last
+ of them has no effect. Consider this example:
+
+ ...(*COMMIT)(*PRUNE)...
+
+ If there is a matching failure to the right, backtracking onto (*PRUNE)
+ causes it to be triggered, and its action is taken. There can never be
+ a backtrack onto (*COMMIT).
+
+ Backtracking verbs in repeated groups
+
+ PCRE differs from Perl in its handling of backtracking verbs in
+ repeated groups. For example, consider:
+
+ /(a(*COMMIT)b)+ac/
+
+ If the subject is "abac", Perl matches, but PCRE fails because the
+ (*COMMIT) in the second repeat of the group acts.
+
+ Backtracking verbs in assertions
+
+ (*FAIL) in an assertion has its normal effect: it forces an immediate
+ backtrack.
+
+ (*ACCEPT) in a positive assertion causes the assertion to succeed with-
+ out any further processing. In a negative assertion, (*ACCEPT) causes
+ the assertion to fail without any further processing.
- (A(*COMMIT)B(*THEN)C|D)
+ The other backtracking verbs are not treated specially if they appear
+ in a positive assertion. In particular, (*THEN) skips to the next
+ alternative in the innermost enclosing group that has alternations,
+ whether or not this is within the assertion.
- 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.
+ Negative assertions are, however, different, in order to ensure that
+ changing a positive assertion into a negative assertion changes its
+ result. Backtracking into (*COMMIT), (*SKIP), or (*PRUNE) causes a neg-
+ ative assertion to be true, without considering any further alternative
+ branches in the assertion. Backtracking into (*THEN) causes it to skip
+ to the next enclosing alternative within the assertion (the normal be-
+ haviour), but if the assertion does not have such an alternative,
+ (*THEN) behaves like (*PRUNE).
+
+ Backtracking verbs in subroutines
+
+ These behaviours occur whether or not the subpattern is called recur-
+ sively. Perl's treatment of subroutines is different in some cases.
+
+ (*FAIL) in a subpattern called as a subroutine has its normal effect:
+ it forces an immediate backtrack.
+
+ (*ACCEPT) in a subpattern called as a subroutine causes the subroutine
+ match to succeed without any further processing. Matching then contin-
+ ues after the subroutine call.
+
+ (*COMMIT), (*SKIP), and (*PRUNE) in a subpattern called as a subroutine
+ cause the subroutine match to fail.
+
+ (*THEN) skips to the next alternative in the innermost enclosing group
+ within the subpattern that has alternatives. If there is no such group
+ within the subpattern, (*THEN) causes the subroutine match to fail.
SEE ALSO
@@ -7178,18 +7618,18 @@ AUTHOR
REVISION
- Last updated: 11 November 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 03 December 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCRESYNTAX(3) PCRESYNTAX(3)
+PCRESYNTAX(3) Library Functions Manual PCRESYNTAX(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
PCRE REGULAR EXPRESSION SYNTAX SUMMARY
The full syntax and semantics of the regular expressions that are sup-
@@ -7212,10 +7652,15 @@ CHARACTERS
\n newline (hex 0A)
\r carriage return (hex 0D)
\t tab (hex 09)
+ \0dd character with octal code 0dd
\ddd character with octal code ddd, or backreference
+ \o{ddd..} character with octal code ddd..
\xhh character with hex code hh
\x{hhh..} character with hex code hhh..
+ Note that \0dd is always an octal code, and that \8 and \9 are the lit-
+ eral characters "8" and "9".
+
CHARACTER TYPES
@@ -7238,9 +7683,12 @@ CHARACTER TYPES
\W a "non-word" character
\X a Unicode extended grapheme cluster
- In PCRE, by default, \d, \D, \s, \S, \w, and \W recognize only ASCII
- characters, even in a UTF mode. However, this can be changed by setting
- the PCRE_UCP option.
+ By default, \d, \s, and \w match only ASCII characters, even in UTF-8
+ mode or in the 16- bit and 32-bit libraries. However, if locale-spe-
+ cific matching is happening, \s and \w may also match characters with
+ code points in the range 128-255. If the PCRE_UCP option is set, the
+ behaviour of these escape sequences is changed to use Unicode proper-
+ ties and they match many more characters.
GENERAL CATEGORY PROPERTIES FOR \p and \P
@@ -7295,27 +7743,32 @@ PCRE SPECIAL CATEGORY PROPERTIES FOR \p and \P
Xan Alphanumeric: union of properties L and N
Xps POSIX space: property Z or tab, NL, VT, FF, CR
- Xsp Perl space: property Z or tab, NL, FF, CR
+ Xsp Perl space: property Z or tab, NL, VT, FF, CR
+ Xuc Univerally-named character: one that can be
+ represented by a Universal Character Name
Xwd Perl word: property Xan or underscore
+ Perl and POSIX space are now the same. Perl added VT to its space char-
+ acter set at release 5.18 and PCRE changed at release 8.34.
+
SCRIPT NAMES FOR \p AND \P
- 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,
+ 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,
+ 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.
@@ -7342,8 +7795,8 @@ CHARACTER CLASSES
word same as \w
xdigit hexadecimal digit
- In PCRE, POSIX character set names recognize only ASCII characters by
- default, but some of them use Unicode properties if PCRE_UCP is set.
+ In PCRE, POSIX character set names recognize only ASCII characters by
+ default, but some of them use Unicode properties if PCRE_UCP is set.
You can use \Q...\E inside a character class.
@@ -7424,9 +7877,11 @@ OPTION SETTING
(?x) extended (ignore white space)
(?-...) unset option(s)
- The following are recognized only at the start of a pattern or after
+ The following are recognized only at the start of a pattern or after
one of the newline-setting options with similar syntax:
+ (*LIMIT_MATCH=d) set the match limit to d (decimal number)
+ (*LIMIT_RECURSION=d) set the recursion limit to d (decimal number)
(*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
(*UTF8) set UTF-8 mode: 8-bit library (PCRE_UTF8)
(*UTF16) set UTF-16 mode: 16-bit library (PCRE_UTF16)
@@ -7434,6 +7889,9 @@ OPTION SETTING
(*UTF) set appropriate UTF mode for the library in use
(*UCP) set PCRE_UCP (use Unicode properties for \d etc)
+ Note that LIMIT_MATCH and LIMIT_RECURSION can only reduce the value of
+ the limits set by the caller of pcre_exec(), not increase them.
+
LOOKAHEAD AND LOOKBEHIND ASSERTIONS
@@ -7558,18 +8016,18 @@ AUTHOR
REVISION
- Last updated: 11 November 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 12 November 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCREUNICODE(3) PCREUNICODE(3)
+PCREUNICODE(3) Library Functions Manual PCREUNICODE(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
UTF-8, UTF-16, UTF-32, AND UNICODE PROPERTY SUPPORT
As well as UTF-8 support, PCRE also supports UTF-16 (from release 8.30)
@@ -7632,7 +8090,9 @@ UNICODE PROPERTY SUPPORT
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 the surrogate area and the non-characters.
+ ing the surrogate area. (From release 8.33 the so-called "non-charac-
+ ter" code points are no longer excluded because Unicode corrigendum #9
+ makes it clear that they should not be.)
Characters in the "Surrogate Area" of Unicode are reserved for use by
UTF-16, where they are used in pairs to encode codepoints with values
@@ -7641,10 +8101,6 @@ UNICODE PROPERTY SUPPORT
other words, the whole surrogate thing is a fudge for UTF-16 which
unfortunately messes up UTF-8 and UTF-32.)
- Also excluded are the "Non-Character" code points, which are U+FDD0 to
- U+FDEF and the last two code points in each plane, U+??FFFE and
- U+??FFFF.
-
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()
@@ -7676,10 +8132,6 @@ UNICODE PROPERTY SUPPORT
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.
- Excluded are the "Non-Character" code points, which are U+FDD0 to
- U+FDEF and the last two code points in each plane, U+??FFFE and
- U+??FFFF.
-
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
@@ -7701,77 +8153,76 @@ UNICODE PROPERTY SUPPORT
are passed as patterns and subjects are (by default) checked for valid-
ity on entry to the relevant functions. This check allows only values
in the range U+0 to U+10FFFF, excluding the surrogate area U+D800 to
- U+DFFF, and the "Non-Character" code points, which are U+FDD0 to U+FDEF
- and the last two characters in each plane, U+??FFFE and U+??FFFF.
+ U+DFFF.
- If an invalid UTF-32 string is passed to PCRE, an error return is
- given. At compile time, the only additional information is the offset
+ If an invalid UTF-32 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
pcre32_exec() and pcre32_dfa_exec() also pass back this information, as
- well as a more detailed reason code if the caller has provided memory
+ 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_UTF32_CHECK flag at compile time or at
+ 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_UTF32_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-32 sequences. In this case, it does not
- diagnose an invalid UTF-32 string. However, if an invalid string is
+ diagnose an invalid UTF-32 string. However, if an invalid string is
passed, the result is undefined.
General comments about UTF modes
- 1. Codepoints less than 256 can be specified in patterns by either
+ 1. Codepoints less than 256 can be specified in patterns 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
+ 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
+ 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, or a single 32-bit
- data unit in UTF-32 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|32]_dfa_exec(), nor is it
+ 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, or a single 32-bit
+ data unit in UTF-32 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|32]_dfa_exec(), nor is it
supported in UTF mode by the JIT optimization of pcre[16|32]_exec(). If
- JIT optimization is requested for a UTF pattern that contains \C, it
+ 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
+ 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,
+ 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 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
+ 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
+ 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
+ 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,
+ 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.
- A few Unicode characters such as Greek sigma have more than two code-
+ 9. Case-insensitive matching applies only to characters whose values
+ are less than 128, unless PCRE is built with Unicode property support.
+ A few Unicode characters such as Greek sigma have more than two code-
points that are case-equivalent. Up to and including PCRE release 8.31,
- only one-to-one case mappings were supported, but later releases (with
- Unicode property support) do treat as case-equivalent all versions of
+ only one-to-one case mappings were supported, but later releases (with
+ Unicode property support) do treat as case-equivalent all versions of
characters such as Greek sigma.
@@ -7784,18 +8235,18 @@ AUTHOR
REVISION
- Last updated: 11 November 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 27 February 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCREJIT(3) PCREJIT(3)
+PCREJIT(3) Library Functions Manual 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
@@ -7941,15 +8392,9 @@ UNSUPPORTED OPTIONS AND PATTERN ITEMS
BOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PAR-
TIAL_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) )
-
- Support for some of these may be added in future.
+ The only unsupported pattern items are \C (match a single data unit)
+ when running in a UTF mode, and a callout immediately before an asser-
+ tion condition in a conditional group.
RETURN VALUES FROM JIT EXECUTION
@@ -8203,18 +8648,18 @@ AUTHOR
REVISION
- Last updated: 31 October 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 17 March 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCREPARTIAL(3) PCREPARTIAL(3)
+PCREPARTIAL(3) Library Functions Manual PCREPARTIAL(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
PARTIAL MATCHING IN PCRE
In normal use of PCRE, if the subject string that is passed to a match-
@@ -8273,7 +8718,7 @@ PARTIAL MATCHING USING pcre_exec() OR pcre[16|32]_exec()
A partial match occurs during a call to pcre_exec() or
pcre[16|32]_exec() when the end of the subject string is reached suc-
cessfully, but matching cannot continue because more characters are
- needed. However, at least one character in the subject must have been
+ 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
@@ -8286,18 +8731,22 @@ PARTIAL MATCHING USING pcre_exec() OR pcre[16|32]_exec()
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.
+ If there are at least three slots in the offsets vector, the third slot
+ is set to the offset of the character where matching started.
- For the majority of patterns, the first offset identifies the start of
- the partially matched string. However, for patterns that contain look-
- behind assertions, or \K, or begin with \b or \B, earlier characters
- have been inspected while carrying out the match. For example:
+ For the majority of patterns, the contents of the first and third slots
+ will be the same. However, for patterns that contain lookbehind asser-
+ tions, or begin with \b or \B, characters before the one where matching
+ started may have been inspected while carrying out the match. For exam-
+ ple, consider this pattern:
/(?<=abc)123/
This pattern matches "123", but only if it is preceded by "abc". If the
- subject string is "xyzabc12", the offsets after a partial match are for
- the substring "abc12", because all these characters are needed if
- another match is tried with extra characters added to the subject.
+ subject string is "xyzabc12", the first two offsets after a partial
+ match are for the substring "abc12", because all these characters were
+ inspected. However, the third offset is set to 6, because that is the
+ offset where matching began.
What happens when a partial match is identified depends on which of the
two partial matching options are set.
@@ -8491,6 +8940,16 @@ MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre[16|32]_dfa_exec()
matched string. It is up to the calling program to do that if it needs
to.
+ That means that, for an unanchored pattern, if a continued match fails,
+ it is not possible to try again at a new starting point. All this
+ facility is capable of doing is continuing with the previous match
+ attempt. In the previous example, if the second set of data is "ug23"
+ the result is no match, even though there would be a match for "aug23"
+ if the entire string were given at once. Depending on the application,
+ this may or may not be what you want. The only way to allow for start-
+ ing again at the next character is to retain the matched part of the
+ subject and try a new complete match.
+
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
@@ -8523,10 +8982,9 @@ MULTI-SEGMENT MATCHING WITH pcre_exec() OR pcre[16|32]_exec()
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.
+ characters that precede the start of what would be returned for a com-
+ plete match, because it contains all the characters that were inspected
+ during the partial match.
ISSUES WITH MULTI-SEGMENT MATCHING
@@ -8535,23 +8993,44 @@ ISSUES WITH MULTI-SEGMENT MATCHING
whichever matching function is used.
1. If the pattern contains a test for the beginning of a line, you need
- to pass the PCRE_NOTBOL option when the subject string for any call
- does start at the beginning of a line. There is also a PCRE_NOTEOL
+ to pass the PCRE_NOTBOL option when the subject string for any call
+ does start at the beginning of a line. There is also a PCRE_NOTEOL
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 that have already been obeyed are catered for
+ 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
+ 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
- pcre[16|32]_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
+ pcre[16|32]_fullinfo() functions to obtain the length of the longest
+ 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.)
+ From release 8.33, there is a more accurate way of deciding which char-
+ acters to retain. Instead of subtracting the length of the longest
+ lookbehind from the earliest inspected character (offsets[0]), the
+ match start position (offsets[2]) should be used, and the next match
+ attempt started at the offsets[2] character by setting the startoffset
+ argument of pcre_exec() or pcre_dfa_exec().
+
+ For example, if the pattern "(?<=123)abc" is partially matched against
+ the string "xx123a", the three offset values returned are 2, 6, and 5.
+ This indicates that the matching process that gave a partial match
+ started at offset 5, but the characters "123a" were all inspected. The
+ maximum lookbehind for that pattern is 3, so taking that away from 5
+ shows that we need only keep "123a", and the next match attempt can be
+ started at offset 3 (that is, at "a") when further characters have been
+ added. When the match start is not the earliest inspected character,
+ pcretest shows it explicitly:
+
+ re> "(?<=123)abc"
+ data> xx123a\P\P
+ Partial match at offset 5: 123a
+
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:
@@ -8654,18 +9133,18 @@ AUTHOR
REVISION
- Last updated: 24 June 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 02 July 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCREPRECOMPILE(3) PCREPRECOMPILE(3)
+PCREPRECOMPILE(3) Library Functions Manual PCREPRECOMPILE(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
SAVING AND RE-USING PRECOMPILED PCRE PATTERNS
If you are running an application that uses a large number of regular
@@ -8758,6 +9237,10 @@ RE-USING A PRECOMPILED PATTERN
is used to pass this data, as described in the section on matching a
pattern in the pcreapi documentation.
+ Warning: The tables that pcre_exec() and pcre_dfa_exec() use must be
+ the same as those that were used when the pattern was compiled. If this
+ is not the case, the behaviour is undefined.
+
If you did not provide custom character tables when the pattern was
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
@@ -8789,18 +9272,18 @@ AUTHOR
REVISION
- Last updated: 24 June 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 12 November 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCREPERFORM(3) PCREPERFORM(3)
+PCREPERFORM(3) Library Functions Manual PCREPERFORM(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
PCRE PERFORMANCE
Two aspects of performance are discussed below: memory usage and pro-
@@ -8964,14 +9447,14 @@ REVISION
------------------------------------------------------------------------------
-PCREPOSIX(3) PCREPOSIX(3)
+PCREPOSIX(3) Library Functions Manual PCREPOSIX(3)
+
NAME
PCRE - Perl-compatible regular expressions.
-
-SYNOPSIS OF POSIX API
+SYNOPSIS
#include <pcreposix.h>
@@ -8980,8 +9463,7 @@ SYNOPSIS OF POSIX API
int regexec(regex_t *preg, const char *string,
size_t nmatch, regmatch_t pmatch[], int eflags);
-
- size_t regerror(int errcode, const regex_t *preg,
+ size_t regerror(int errcode, const regex_t *preg,
char *errbuf, size_t errbuf_size);
void regfree(regex_t *preg);
@@ -9229,13 +9711,13 @@ REVISION
------------------------------------------------------------------------------
-PCRECPP(3) PCRECPP(3)
+PCRECPP(3) Library Functions Manual PCRECPP(3)
+
NAME
PCRE - Perl-compatible regular expressions.
-
SYNOPSIS OF C++ WRAPPER
#include <pcrecpp.h>
@@ -9572,13 +10054,13 @@ REVISION
------------------------------------------------------------------------------
-PCRESAMPLE(3) PCRESAMPLE(3)
+PCRESAMPLE(3) Library Functions Manual PCRESAMPLE(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
PCRE SAMPLE PROGRAM
A simple, complete demonstration program, to get you started with using
@@ -9658,51 +10140,56 @@ REVISION
Last updated: 10 January 2012
Copyright (c) 1997-2012 University of Cambridge.
------------------------------------------------------------------------------
-PCRELIMITS(3) PCRELIMITS(3)
+PCRELIMITS(3) Library Functions Manual 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, 32-bit units for the 32-bit
+ units (bytes for the 8-bit library, 16-bit units for the 16-bit
library, and 32-bit units for the 32-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
- or 32-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
+ with the default internal linkage size, which is 2 bytes for the 8-bit
+ and 16-bit libraries, and 4 bytes for the 32-bit library. 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
+ or 32-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.
+ can be no more than 65535 capturing subpatterns. There is, however, a
+ limit to the depth of nesting of parenthesized subpatterns of all
+ kinds. This is imposed in order to limit the amount of system stack
+ used at compile time. The limit can be specified when PCRE is built;
+ the default is 250.
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
+ 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 and
- 32-bit library.
+ 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 and
+ 32-bit libraries.
- The maximum length of a subject string is the largest positive number
- that an integer variable can hold. However, when using the traditional
+ 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
+ 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.
@@ -9716,18 +10203,18 @@ AUTHOR
REVISION
- Last updated: 04 May 2012
- Copyright (c) 1997-2012 University of Cambridge.
+ Last updated: 05 November 2013
+ Copyright (c) 1997-2013 University of Cambridge.
------------------------------------------------------------------------------
-PCRESTACK(3) PCRESTACK(3)
+PCRESTACK(3) Library Functions Manual PCRESTACK(3)
+
NAME
PCRE - Perl-compatible regular expressions
-
PCRE DISCUSSION OF STACK USAGE
When you call pcre[16|32]_exec(), it makes use of an internal function
diff --git a/ext/pcre/pcrelib/pcre.h b/ext/pcre/pcrelib/pcre.h
index a6aa4e934b..c85f36b6bc 100644
--- a/ext/pcre/pcrelib/pcre.h
+++ b/ext/pcre/pcrelib/pcre.h
@@ -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-2012 University of Cambridge
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
/* The current PCRE version information. */
#define PCRE_MAJOR 8
-#define PCRE_MINOR 32
+#define PCRE_MINOR 34
#define PCRE_PRERELEASE
-#define PCRE_DATE 2012-11-30
+#define PCRE_DATE 2013-12-15
/* 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
@@ -96,11 +96,14 @@ extern "C" {
#endif
/* Public 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. Any of the
-compile-time options may be inspected during studying (and therefore JIT
-compiling).
+are both. Most of the compile-time options are saved with the compiled regex so
+that they can be inspected during studying (and therefore JIT compiling). Note
+that pcre_study() has its own set of options. Originally, all the options
+defined here used distinct bits. However, almost all the bits in a 32-bit word
+are now used, so in order to conserve them, option bits that were previously
+only recognized at matching time (i.e. by pcre_exec() or pcre_dfa_exec()) may
+also be used for compile-time options that affect only compiling and are not
+relevant for studying or JIT compiling.
Some options for pcre_compile() change its behaviour but do not affect the
behaviour of the execution functions. Other options are passed through to the
@@ -142,8 +145,15 @@ with J. */
#define PCRE_AUTO_CALLOUT 0x00004000 /* C1 */
#define PCRE_PARTIAL_SOFT 0x00008000 /* E D J ) Synonyms */
#define PCRE_PARTIAL 0x00008000 /* E D J ) */
-#define PCRE_DFA_SHORTEST 0x00010000 /* D */
-#define PCRE_DFA_RESTART 0x00020000 /* D */
+
+/* This pair use the same bit. */
+#define PCRE_NEVER_UTF 0x00010000 /* C1 ) Overlaid */
+#define PCRE_DFA_SHORTEST 0x00010000 /* D ) Overlaid */
+
+/* This pair use the same bit. */
+#define PCRE_NO_AUTO_POSSESS 0x00020000 /* C1 ) Overlaid */
+#define PCRE_DFA_RESTART 0x00020000 /* D ) Overlaid */
+
#define PCRE_FIRSTLINE 0x00040000 /* C3 */
#define PCRE_DUPNAMES 0x00080000 /* C1 */
#define PCRE_NEWLINE_CR 0x00100000 /* C3 E D */
@@ -199,6 +209,7 @@ with J. */
#define PCRE_ERROR_DFA_BADRESTART (-30)
#define PCRE_ERROR_JIT_BADOPTION (-31)
#define PCRE_ERROR_BADLENGTH (-32)
+#define PCRE_ERROR_UNSET (-33)
/* Specific error codes for UTF-8 validity checks */
@@ -224,7 +235,7 @@ with J. */
#define PCRE_UTF8_ERR19 19
#define PCRE_UTF8_ERR20 20
#define PCRE_UTF8_ERR21 21
-#define PCRE_UTF8_ERR22 22
+#define PCRE_UTF8_ERR22 22 /* Unused (was non-character) */
/* Specific error codes for UTF-16 validity checks */
@@ -232,13 +243,13 @@ with J. */
#define PCRE_UTF16_ERR1 1
#define PCRE_UTF16_ERR2 2
#define PCRE_UTF16_ERR3 3
-#define PCRE_UTF16_ERR4 4
+#define PCRE_UTF16_ERR4 4 /* Unused (was non-character) */
/* Specific error codes for UTF-32 validity checks */
#define PCRE_UTF32_ERR0 0
#define PCRE_UTF32_ERR1 1
-#define PCRE_UTF32_ERR2 2
+#define PCRE_UTF32_ERR2 2 /* Unused (was non-character) */
#define PCRE_UTF32_ERR3 3
/* Request types for pcre_fullinfo() */
@@ -263,10 +274,13 @@ with J. */
#define PCRE_INFO_JIT 16
#define PCRE_INFO_JITSIZE 17
#define PCRE_INFO_MAXLOOKBEHIND 18
-#define PCRE_INFO_FIRSTCHARACTER 19
-#define PCRE_INFO_FIRSTCHARACTERFLAGS 20
+#define PCRE_INFO_FIRSTCHARACTER 19
+#define PCRE_INFO_FIRSTCHARACTERFLAGS 20
#define PCRE_INFO_REQUIREDCHAR 21
-#define PCRE_INFO_REQUIREDCHARFLAGS 22
+#define PCRE_INFO_REQUIREDCHARFLAGS 22
+#define PCRE_INFO_MATCHLIMIT 23
+#define PCRE_INFO_RECURSIONLIMIT 24
+#define PCRE_INFO_MATCH_EMPTY 25
/* Request types for pcre_config(). Do not re-arrange, in order to remain
compatible. */
@@ -284,6 +298,7 @@ compatible. */
#define PCRE_CONFIG_UTF16 10
#define PCRE_CONFIG_JITTARGET 11
#define PCRE_CONFIG_UTF32 12
+#define PCRE_CONFIG_PARENS_LIMIT 13
/* Request types for pcre_study(). Do not re-arrange, in order to remain
compatible. */
@@ -645,6 +660,9 @@ PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
pcre16_jit_callback, void *);
PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *,
pcre32_jit_callback, void *);
+PCRE_EXP_DECL void pcre_jit_free_unused_memory(void);
+PCRE_EXP_DECL void pcre16_jit_free_unused_memory(void);
+PCRE_EXP_DECL void pcre32_jit_free_unused_memory(void);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/ext/pcre/pcrelib/pcre_chartables.c b/ext/pcre/pcrelib/pcre_chartables.c
index 2a39e9ff33..1e20ec29d0 100644
--- a/ext/pcre/pcrelib/pcre_chartables.c
+++ b/ext/pcre/pcrelib/pcre_chartables.c
@@ -163,7 +163,7 @@ graph, print, punct, and cntrl. Other classes are built from combinations. */
*/
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
- 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
+ 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
diff --git a/ext/pcre/pcrelib/pcre_compile.c b/ext/pcre/pcrelib/pcre_compile.c
index 4997b3b1ec..c170c47a00 100644
--- a/ext/pcre/pcrelib/pcre_compile.c
+++ b/ext/pcre/pcrelib/pcre_compile.c
@@ -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-2012 University of Cambridge
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -115,6 +115,13 @@ kicks in at the same number of forward references in all cases. */
#define COMPILE_WORK_SIZE (2048*LINK_SIZE)
#define COMPILE_WORK_SIZE_MAX (100*COMPILE_WORK_SIZE)
+/* This value determines the size of the initial vector that is used for
+remembering named groups during the pre-compile. It is allocated on the stack,
+but if it is too small, it is expanded using malloc(), in a similar way to the
+workspace. The value is the number of slots in the list. */
+
+#define NAMED_GROUP_LIST_SIZE 20
+
/* 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. */
@@ -253,11 +260,25 @@ static const verbitem verbs[] = {
static const int verbcount = sizeof(verbs)/sizeof(verbitem);
+/* Substitutes for [[:<:]] and [[:>:]], which mean start and end of word in
+another regex library. */
+
+static const pcre_uchar sub_start_of_word[] = {
+ CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK,
+ CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w, CHAR_RIGHT_PARENTHESIS, '\0' };
+
+static const pcre_uchar sub_end_of_word[] = {
+ CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK,
+ CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w,
+ CHAR_RIGHT_PARENTHESIS, '\0' };
+
+
/* Tables of names of POSIX character classes and their lengths. The names are
now all in a single string, to reduce the number of relocations when a shared
library is dynamically loaded. The list of lengths is terminated by a zero
length entry. The first three must be alpha, lower, upper, as this is assumed
-for handling case independence. */
+for handling case independence. The indices for graph, print, and punct are
+needed, so identify them. */
static const char posix_names[] =
STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0
@@ -268,6 +289,11 @@ static const char posix_names[] =
static const pcre_uint8 posix_name_lengths[] = {
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
+#define PC_GRAPH 8
+#define PC_PRINT 9
+#define PC_PUNCT 10
+
+
/* Table of class bit maps for each POSIX class. Each class is formed from a
base map, with an optional addition or removal of another map. Then, for some
classes, there is some additional tweaking: for [:blank:] the vertical space
@@ -295,9 +321,8 @@ static const int posix_class_maps[] = {
cbit_xdigit,-1, 0 /* xdigit */
};
-/* Table of substitutes for \d etc when PCRE_UCP is set. The POSIX class
-substitutes must be in the order of the names, defined above, and there are
-both positive and negative cases. NULL means no substitute. */
+/* Table of substitutes for \d etc when PCRE_UCP is set. They are replaced by
+Unicode property escapes. */
#ifdef SUPPORT_UCP
static const pcre_uchar string_PNd[] = {
@@ -322,12 +347,18 @@ static const pcre_uchar string_pXwd[] = {
static const pcre_uchar *substitutes[] = {
string_PNd, /* \D */
string_pNd, /* \d */
- string_PXsp, /* \S */ /* NOTE: Xsp is Perl space */
- string_pXsp, /* \s */
+ string_PXsp, /* \S */ /* Xsp is Perl space, but from 8.34, Perl */
+ string_pXsp, /* \s */ /* space and POSIX space are the same. */
string_PXwd, /* \W */
string_pXwd /* \w */
};
+/* The POSIX class substitutes must be in the order of the POSIX class names,
+defined above, and there are both positive and negative cases. NULL means no
+general substitute of a Unicode property escape (\p or \P). However, for some
+POSIX classes (e.g. graph, print, punct) a special property code is compiled
+directly. */
+
static const pcre_uchar string_pL[] = {
CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
@@ -375,8 +406,8 @@ static const pcre_uchar *posix_substitutes[] = {
NULL, /* graph */
NULL, /* print */
NULL, /* punct */
- string_pXps, /* space */ /* NOTE: Xps is POSIX space */
- string_pXwd, /* word */
+ string_pXps, /* space */ /* Xps is POSIX space, but from 8.34 */
+ string_pXwd, /* word */ /* Perl and POSIX space are the same */
NULL, /* xdigit */
/* Negated cases */
string_PL, /* ^alpha */
@@ -390,8 +421,8 @@ static const pcre_uchar *posix_substitutes[] = {
NULL, /* ^graph */
NULL, /* ^print */
NULL, /* ^punct */
- string_PXps, /* ^space */ /* NOTE: Xps is POSIX space */
- string_PXwd, /* ^word */
+ string_PXps, /* ^space */ /* Xps is POSIX space, but from 8.34 */
+ string_PXwd, /* ^word */ /* Perl and POSIX space are the same */
NULL /* ^xdigit */
};
#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(pcre_uchar *))
@@ -455,7 +486,7 @@ static const char error_texts[] =
"POSIX collating elements are not supported\0"
"this version of PCRE is compiled without UTF support\0"
"spare error\0" /** DEAD **/
- "character value in \\x{...} sequence is too large\0"
+ "character value in \\x{} or \\o{} is too large\0"
/* 35 */
"invalid condition (?(0)\0"
"\\C not allowed in lookbehind assertion\0"
@@ -487,7 +518,7 @@ static const char error_texts[] =
"a numbered reference must not be zero\0"
"an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0"
/* 60 */
- "(*VERB) not recognized\0"
+ "(*VERB) not recognized or malformed\0"
"number is too big\0"
"subpattern name expected\0"
"digit expected after (?+\0"
@@ -508,6 +539,14 @@ static const char error_texts[] =
"name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0"
"character value in \\u.... sequence is too large\0"
"invalid UTF-32 string\0"
+ "setting UTF is disabled by the application\0"
+ "non-hex character in \\x{} (closing brace missing?)\0"
+ /* 80 */
+ "non-octal character in \\o{} (closing brace missing?)\0"
+ "missing opening brace after \\o\0"
+ "parentheses are too deeply nested\0"
+ "invalid range in character class\0"
+ "group name must start with a non-digit\0"
;
/* Table to identify digits and hex digits. This is used when compiling
@@ -647,6 +686,183 @@ static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */
#endif
+/* This table is used to check whether auto-possessification is possible
+between adjacent character-type opcodes. The left-hand (repeated) opcode is
+used to select the row, and the right-hand opcode is use to select the column.
+A value of 1 means that auto-possessification is OK. For example, the second
+value in the first row means that \D+\d can be turned into \D++\d.
+
+The Unicode property types (\P and \p) have to be present to fill out the table
+because of what their opcode values are, but the table values should always be
+zero because property types are handled separately in the code. The last four
+columns apply to items that cannot be repeated, so there is no need to have
+rows for them. 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. */
+
+#define APTROWS (LAST_AUTOTAB_LEFT_OP - FIRST_AUTOTAB_OP + 1)
+#define APTCOLS (LAST_AUTOTAB_RIGHT_OP - FIRST_AUTOTAB_OP + 1)
+
+static const pcre_uint8 autoposstab[APTROWS][APTCOLS] = {
+/* \D \d \S \s \W \w . .+ \C \P \p \R \H \h \V \v \X \Z \z $ $M */
+ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \D */
+ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \d */
+ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \S */
+ { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \s */
+ { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \W */
+ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \w */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* . */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* .+ */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \C */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \P */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \p */
+ { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \R */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \H */
+ { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \h */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \V */
+ { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0 }, /* \v */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } /* \X */
+};
+
+
+/* This table is used to check whether auto-possessification is possible
+between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP). The
+left-hand (repeated) opcode is used to select the row, and the right-hand
+opcode is used to select the column. The values are as follows:
+
+ 0 Always return FALSE (never auto-possessify)
+ 1 Character groups are distinct (possessify if both are OP_PROP)
+ 2 Check character categories in the same group (general or particular)
+ 3 TRUE if the two opcodes are not the same (PROP vs NOTPROP)
+
+ 4 Check left general category vs right particular category
+ 5 Check right general category vs left particular category
+
+ 6 Left alphanum vs right general category
+ 7 Left space vs right general category
+ 8 Left word vs right general category
+
+ 9 Right alphanum vs left general category
+ 10 Right space vs left general category
+ 11 Right word vs left general category
+
+ 12 Left alphanum vs right particular category
+ 13 Left space vs right particular category
+ 14 Left word vs right particular category
+
+ 15 Right alphanum vs left particular category
+ 16 Right space vs left particular category
+ 17 Right word vs left particular category
+*/
+
+static const pcre_uint8 propposstab[PT_TABSIZE][PT_TABSIZE] = {
+/* ANY LAMP GC PC SC ALNUM SPACE PXSPACE WORD CLIST UCNC */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_ANY */
+ { 0, 3, 0, 0, 0, 3, 1, 1, 0, 0, 0 }, /* PT_LAMP */
+ { 0, 0, 2, 4, 0, 9, 10, 10, 11, 0, 0 }, /* PT_GC */
+ { 0, 0, 5, 2, 0, 15, 16, 16, 17, 0, 0 }, /* PT_PC */
+ { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 }, /* PT_SC */
+ { 0, 3, 6, 12, 0, 3, 1, 1, 0, 0, 0 }, /* PT_ALNUM */
+ { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_SPACE */
+ { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_PXSPACE */
+ { 0, 0, 8, 14, 0, 0, 1, 1, 3, 0, 0 }, /* PT_WORD */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_CLIST */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 } /* PT_UCNC */
+};
+
+/* This table is used to check whether auto-possessification is possible
+between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP) when one
+specifies a general category and the other specifies a particular category. The
+row is selected by the general category and the column by the particular
+category. The value is 1 if the particular category is not part of the general
+category. */
+
+static const pcre_uint8 catposstab[7][30] = {
+/* Cc Cf Cn Co Cs Ll Lm Lo Lt Lu Mc Me Mn Nd Nl No Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So Zl Zp Zs */
+ { 0, 0, 0, 0, 0, 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 }, /* C */
+ { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* L */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* M */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* N */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 }, /* P */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 }, /* S */
+ { 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, 0, 0, 0 } /* Z */
+};
+
+/* This table is used when checking ALNUM, (PX)SPACE, SPACE, and WORD against
+a general or particular category. The properties in each row are those
+that apply to the character set in question. Duplication means that a little
+unnecessary work is done when checking, but this keeps things much simpler
+because they can all use the same code. For more details see the comment where
+this table is used.
+
+Note: SPACE and PXSPACE used to be different because Perl excluded VT from
+"space", but from Perl 5.18 it's included, so both categories are treated the
+same here. */
+
+static const pcre_uint8 posspropstab[3][4] = {
+ { ucp_L, ucp_N, ucp_N, ucp_Nl }, /* ALNUM, 3rd and 4th values redundant */
+ { ucp_Z, ucp_Z, ucp_C, ucp_Cc }, /* SPACE and PXSPACE, 2nd value redundant */
+ { ucp_L, ucp_N, ucp_P, ucp_Po } /* WORD */
+};
+
+/* This table is used when converting repeating opcodes into possessified
+versions as a result of an explicit possessive quantifier such as ++. A zero
+value means there is no possessified version - in those cases the item in
+question must be wrapped in ONCE brackets. The table is truncated at OP_CALLOUT
+because all relevant opcodes are less than that. */
+
+static const pcre_uint8 opcode_possessify[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 15 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 31 */
+
+ 0, /* NOTI */
+ OP_POSSTAR, 0, /* STAR, MINSTAR */
+ OP_POSPLUS, 0, /* PLUS, MINPLUS */
+ OP_POSQUERY, 0, /* QUERY, MINQUERY */
+ OP_POSUPTO, 0, /* UPTO, MINUPTO */
+ 0, /* EXACT */
+ 0, 0, 0, 0, /* POS{STAR,PLUS,QUERY,UPTO} */
+
+ OP_POSSTARI, 0, /* STARI, MINSTARI */
+ OP_POSPLUSI, 0, /* PLUSI, MINPLUSI */
+ OP_POSQUERYI, 0, /* QUERYI, MINQUERYI */
+ OP_POSUPTOI, 0, /* UPTOI, MINUPTOI */
+ 0, /* EXACTI */
+ 0, 0, 0, 0, /* POS{STARI,PLUSI,QUERYI,UPTOI} */
+
+ OP_NOTPOSSTAR, 0, /* NOTSTAR, NOTMINSTAR */
+ OP_NOTPOSPLUS, 0, /* NOTPLUS, NOTMINPLUS */
+ OP_NOTPOSQUERY, 0, /* NOTQUERY, NOTMINQUERY */
+ OP_NOTPOSUPTO, 0, /* NOTUPTO, NOTMINUPTO */
+ 0, /* NOTEXACT */
+ 0, 0, 0, 0, /* NOTPOS{STAR,PLUS,QUERY,UPTO} */
+
+ OP_NOTPOSSTARI, 0, /* NOTSTARI, NOTMINSTARI */
+ OP_NOTPOSPLUSI, 0, /* NOTPLUSI, NOTMINPLUSI */
+ OP_NOTPOSQUERYI, 0, /* NOTQUERYI, NOTMINQUERYI */
+ OP_NOTPOSUPTOI, 0, /* NOTUPTOI, NOTMINUPTOI */
+ 0, /* NOTEXACTI */
+ 0, 0, 0, 0, /* NOTPOS{STARI,PLUSI,QUERYI,UPTOI} */
+
+ OP_TYPEPOSSTAR, 0, /* TYPESTAR, TYPEMINSTAR */
+ OP_TYPEPOSPLUS, 0, /* TYPEPLUS, TYPEMINPLUS */
+ OP_TYPEPOSQUERY, 0, /* TYPEQUERY, TYPEMINQUERY */
+ OP_TYPEPOSUPTO, 0, /* TYPEUPTO, TYPEMINUPTO */
+ 0, /* TYPEEXACT */
+ 0, 0, 0, 0, /* TYPEPOS{STAR,PLUS,QUERY,UPTO} */
+
+ OP_CRPOSSTAR, 0, /* CRSTAR, CRMINSTAR */
+ OP_CRPOSPLUS, 0, /* CRPLUS, CRMINPLUS */
+ OP_CRPOSQUERY, 0, /* CRQUERY, CRMINQUERY */
+ OP_CRPOSRANGE, 0, /* CRRANGE, CRMINRANGE */
+ 0, 0, 0, 0, /* CRPOS{STAR,PLUS,QUERY,RANGE} */
+
+ 0, 0, 0, /* CLASS, NCLASS, XCLASS */
+ 0, 0, /* REF, REFI */
+ 0, 0, /* DNREF, DNREFI */
+ 0, 0 /* RECURSE, CALLOUT */
+};
+
+
/*************************************************
* Find an error text *
@@ -674,6 +890,7 @@ return s;
}
+
/*************************************************
* Expand the workspace *
*************************************************/
@@ -751,16 +968,15 @@ return (*p == CHAR_RIGHT_CURLY_BRACKET);
*************************************************/
/* This function is called when a \ has been encountered. It either returns a
-positive value for a simple escape such as \n, or 0 for a data character
-which will be placed in chptr. A backreference to group n is returned as
-negative n. When UTF-8 is enabled, a positive value greater than 255 may
-be returned in chptr.
-On entry,ptr is pointing at the \. On exit, it is on the final character of the
-escape sequence.
+positive value for a simple escape such as \n, or 0 for a data character which
+will be placed in chptr. A backreference to group n is returned as negative n.
+When UTF-8 is enabled, a positive value greater than 255 may be returned in
+chptr. On entry, ptr is pointing at the \. On exit, it is on the final
+character of the escape sequence.
Arguments:
ptrptr points to the pattern position pointer
- chptr points to the data character
+ chptr points to a returned data character
errorcodeptr points to the errorcode variable
bracount number of previous extracting brackets
options the options bits
@@ -797,7 +1013,8 @@ Otherwise further processing may be required. */
#ifndef EBCDIC /* ASCII/UTF-8 coding */
/* Not alphanumeric */
else if (c < CHAR_0 || c > CHAR_z) {}
-else if ((i = escapes[c - CHAR_0]) != 0) { if (i > 0) c = (pcre_uint32)i; else escape = -i; }
+else if ((i = escapes[c - CHAR_0]) != 0)
+ { if (i > 0) c = (pcre_uint32)i; else escape = -i; }
#else /* EBCDIC coding */
/* Not alphanumeric */
@@ -847,11 +1064,11 @@ else
}
#if defined COMPILE_PCRE8
- if (c > (utf ? 0x10ffff : 0xff))
+ if (c > (utf ? 0x10ffffU : 0xffU))
#elif defined COMPILE_PCRE16
- if (c > (utf ? 0x10ffff : 0xffff))
+ if (c > (utf ? 0x10ffffU : 0xffffU))
#elif defined COMPILE_PCRE32
- if (utf && c > 0x10ffff)
+ if (utf && c > 0x10ffffU)
#endif
{
*errorcodeptr = ERR76;
@@ -963,16 +1180,20 @@ else
break;
/* The handling of escape sequences consisting of a string of digits
- starting with one that is not zero is not straightforward. By experiment,
- the way Perl works seems to be as follows:
+ starting with one that is not zero is not straightforward. Perl has changed
+ over the years. Nowadays \g{} for backreferences and \o{} for octal are
+ recommended to avoid the ambiguities in the old syntax.
Outside a character class, the digits are read as a decimal number. If the
- number is less than 10, or if there are that many previous extracting
- left brackets, then it is a back reference. Otherwise, up to three octal
- digits are read to form an escaped byte. Thus \123 is likely to be octal
- 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal
- value is greater than 377, the least significant 8 bits are taken. Inside a
- character class, \ followed by a digit is always an octal number. */
+ number is less than 8 (used to be 10), or if there are that many previous
+ extracting left brackets, then it is a back reference. Otherwise, up to
+ three octal digits are read to form an escaped byte. Thus \123 is likely to
+ be octal 123 (cf \0123, which is octal 012 followed by the literal 3). If
+ the octal value is greater than 377, the least significant 8 bits are
+ taken. \8 and \9 are treated as the literal characters 8 and 9.
+
+ Inside a character class, \ followed by a digit is always either a literal
+ 8 or 9 or an octal number. */
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:
@@ -999,7 +1220,7 @@ else
*errorcodeptr = ERR61;
break;
}
- if (s < 10 || s <= bracount)
+ if (s < 8 || s <= bracount) /* Check for back reference */
{
escape = -s;
break;
@@ -1007,16 +1228,14 @@ else
ptr = oldptr; /* Put the pointer back and fall through */
}
- /* Handle an octal number following \. If the first digit is 8 or 9, Perl
- generates a binary zero byte and treats the digit as a following literal.
- Thus we have to pull back the pointer by one. */
+ /* Handle a digit following \ when the number is not a back reference. If
+ the first digit is 8 or 9, Perl used to generate a binary zero byte and
+ then treat the digit as a following literal. At least by Perl 5.18 this
+ changed so as not to insert the binary zero. */
- if ((c = *ptr) >= CHAR_8)
- {
- ptr--;
- c = 0;
- break;
- }
+ if ((c = *ptr) >= CHAR_8) break;
+
+ /* Fall through with a digit less than 8 */
/* \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
@@ -1033,15 +1252,50 @@ else
#endif
break;
- /* \x is complicated. \x{ddd} is a character number which can be greater
- than 0xff in utf or non-8bit mode, but only if the ddd are hex digits.
- If not, { is treated as a data character. */
+ /* \o is a relatively new Perl feature, supporting a more general way of
+ specifying character codes in octal. The only supported form is \o{ddd}. */
+
+ case CHAR_o:
+ if (ptr[1] != CHAR_LEFT_CURLY_BRACKET) *errorcodeptr = ERR81; else
+ {
+ ptr += 2;
+ c = 0;
+ overflow = FALSE;
+ while (*ptr >= CHAR_0 && *ptr <= CHAR_7)
+ {
+ register pcre_uint32 cc = *ptr++;
+ if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
+#ifdef COMPILE_PCRE32
+ if (c >= 0x20000000l) { overflow = TRUE; break; }
+#endif
+ c = (c << 3) + cc - CHAR_0 ;
+#if defined COMPILE_PCRE8
+ if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; }
+#elif defined COMPILE_PCRE16
+ if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; }
+#elif defined COMPILE_PCRE32
+ if (utf && c > 0x10ffffU) { overflow = TRUE; break; }
+#endif
+ }
+ if (overflow)
+ {
+ while (*ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++;
+ *errorcodeptr = ERR34;
+ }
+ else if (*ptr == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
+ }
+ else *errorcodeptr = ERR80;
+ }
+ break;
+
+ /* \x is complicated. In JavaScript, \x must be followed by two hexadecimal
+ numbers. Otherwise it is a lowercase x letter. */
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)
{
@@ -1058,73 +1312,86 @@ else
#endif
}
}
- break;
- }
+ } /* End JavaScript handling */
- if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
- {
- const pcre_uchar *pt = ptr + 2;
+ /* Handle \x in Perl's style. \x{ddd} is a character number which can be
+ greater than 0xff in utf or non-8bit mode, but only if the ddd are hex
+ digits. If not, { used to be treated as a data character. However, Perl
+ seems to read hex digits up to the first non-such, and ignore the rest, so
+ that, for example \x{zz} matches a binary zero. This seems crazy, so PCRE
+ now gives an error. */
- c = 0;
- overflow = FALSE;
- while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0)
+ else
+ {
+ if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
{
- register pcre_uint32 cc = *pt++;
- if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
+ ptr += 2;
+ c = 0;
+ overflow = FALSE;
+ while (MAX_255(*ptr) && (digitab[*ptr] & ctype_xdigit) != 0)
+ {
+ register pcre_uint32 cc = *ptr++;
+ if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
#ifdef COMPILE_PCRE32
- if (c >= 0x10000000l) { overflow = TRUE; break; }
+ if (c >= 0x10000000l) { overflow = TRUE; break; }
#endif
#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));
+ 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));
+ 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
#if defined COMPILE_PCRE8
- if (c > (utf ? 0x10ffff : 0xff)) { overflow = TRUE; break; }
+ if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; }
#elif defined COMPILE_PCRE16
- if (c > (utf ? 0x10ffff : 0xffff)) { overflow = TRUE; break; }
+ if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; }
#elif defined COMPILE_PCRE32
- if (utf && c > 0x10ffff) { overflow = TRUE; break; }
+ if (utf && c > 0x10ffffU) { overflow = TRUE; break; }
#endif
- }
+ }
- if (overflow)
- {
- while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++;
- *errorcodeptr = ERR34;
- }
+ if (overflow)
+ {
+ while (MAX_255(*ptr) && (digitab[*ptr] & ctype_xdigit) != 0) ptr++;
+ *errorcodeptr = ERR34;
+ }
- if (*pt == CHAR_RIGHT_CURLY_BRACKET)
- {
- if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
- ptr = pt;
- break;
- }
+ else if (*ptr == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
+ }
- /* If the sequence of hex digits does not end with '}', then we don't
- recognize this construct; fall through to the normal \x handling. */
- }
+ /* If the sequence of hex digits does not end with '}', give an error.
+ We used just to recognize this construct and fall through to the normal
+ \x handling, but nowadays Perl gives an error, which seems much more
+ sensible, so we do too. */
- /* Read just a single-byte hex-defined char */
+ else *errorcodeptr = ERR79;
+ } /* End of \x{} processing */
- c = 0;
- while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0)
- {
- pcre_uint32 cc; /* Some compilers don't like */
- cc = *(++ptr); /* ++ in initializers */
+ /* Read a single-byte hex-defined char (up to two hex digits after \x) */
+
+ else
+ {
+ c = 0;
+ while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0)
+ {
+ pcre_uint32 cc; /* Some compilers don't like */
+ cc = *(++ptr); /* ++ in initializers */
#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
- c = c * 16 + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
+ c = c * 16 + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
#else /* EBCDIC coding */
- if (cc <= CHAR_z) cc += 64; /* Convert to upper case */
- c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+ if (cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
#endif
- }
+ }
+ } /* End of \xdd handling */
+ } /* End of Perl-style \x handling */
break;
/* For \c, a following letter is upper-cased; then the 0x40 bit is flipped.
@@ -1190,6 +1457,8 @@ if ((options & PCRE_UCP) != 0 && escape >= ESC_D && escape <= ESC_w)
return escape;
}
+
+
#ifdef SUPPORT_UCP
/*************************************************
* Handle \P and \p *
@@ -1287,7 +1556,6 @@ return FALSE;
-
/*************************************************
* Read repeat counts *
*************************************************/
@@ -1356,302 +1624,6 @@ return p;
/*************************************************
-* Subroutine for finding forward reference *
-*************************************************/
-
-/* This recursive function is called only from find_parens() below. The
-top-level call starts at the beginning of the pattern. All other calls must
-start at a parenthesis. It scans along a pattern's text looking for capturing
-subpatterns, and counting them. If it finds a named pattern that matches the
-name it is given, it returns its number. Alternatively, if the name is NULL, it
-returns when it reaches a given numbered subpattern. Recursion is used to keep
-track of subpatterns that reset the capturing group numbers - the (?| feature.
-
-This function was originally called only from the second pass, in which we know
-that if (?< or (?' or (?P< is encountered, the name will be correctly
-terminated because that is checked in the first pass. There is now one call to
-this function in the first pass, to check for a recursive back reference by
-name (so that we can make the whole group atomic). In this case, we need check
-only up to the current position in the pattern, and that is still OK because
-and previous occurrences will have been checked. To make this work, the test
-for "end of pattern" is a check against cd->end_pattern in the main loop,
-instead of looking for a binary zero. This means that the special first-pass
-call can adjust cd->end_pattern temporarily. (Checks for binary zero while
-processing items within the loop are OK, because afterwards the main loop will
-terminate.)
-
-Arguments:
- ptrptr address of the current character pointer (updated)
- cd compile background data
- 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
- utf TRUE if we are in UTF-8 / UTF-16 / UTF-32 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(pcre_uchar **ptrptr, compile_data *cd, const pcre_uchar *name, int lorn,
- BOOL xmode, BOOL utf, int *count)
-{
-pcre_uchar *ptr = *ptrptr;
-int start_count = *count;
-int hwm_count = start_count;
-BOOL dup_parens = FALSE;
-
-/* If the first character is a parenthesis, check on the type of group we are
-dealing with. The very first call may not start with a parenthesis. */
-
-if (ptr[0] == CHAR_LEFT_PARENTHESIS)
- {
- /* Handle specials such as (*SKIP) or (*UTF8) etc. */
-
- if (ptr[1] == CHAR_ASTERISK) ptr += 2;
-
- /* Handle a normal, unnamed capturing parenthesis. */
-
- else if (ptr[1] != CHAR_QUESTION_MARK)
- {
- *count += 1;
- if (name == NULL && *count == lorn) return *count;
- ptr++;
- }
-
- /* All cases now have (? at the start. Remember when we are in a group
- where the parenthesis numbers are duplicated. */
-
- else if (ptr[2] == CHAR_VERTICAL_LINE)
- {
- ptr += 3;
- dup_parens = TRUE;
- }
-
- /* Handle comments; all characters are allowed until a ket is reached. */
-
- else if (ptr[2] == CHAR_NUMBER_SIGN)
- {
- for (ptr += 3; *ptr != CHAR_NULL; ptr++)
- if (*ptr == CHAR_RIGHT_PARENTHESIS) break;
- goto FAIL_EXIT;
- }
-
- /* Handle a condition. If it is an assertion, just carry on so that it
- is processed as normal. If not, skip to the closing parenthesis of the
- condition (there can't be any nested parens). */
-
- else if (ptr[2] == CHAR_LEFT_PARENTHESIS)
- {
- ptr += 2;
- if (ptr[1] != CHAR_QUESTION_MARK)
- {
- while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
- if (*ptr != CHAR_NULL) ptr++;
- }
- }
-
- /* Start with (? but not a condition. */
-
- else
- {
- ptr += 2;
- if (*ptr == CHAR_P) ptr++; /* Allow optional P */
-
- /* We have to disambiguate (?<! and (?<= from (?<name> for named groups */
-
- if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK &&
- ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE)
- {
- pcre_uchar term;
- const pcre_uchar *thisname;
- *count += 1;
- if (name == NULL && *count == lorn) return *count;
- term = *ptr++;
- if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN;
- thisname = ptr;
- while (*ptr != term) ptr++;
- if (name != NULL && lorn == (int)(ptr - thisname) &&
- STRNCMP_UC_UC(name, thisname, (unsigned int)lorn) == 0)
- return *count;
- term++;
- }
- }
- }
-
-/* Past any initial parenthesis handling, scan for parentheses or vertical
-bars. Stop if we get to cd->end_pattern. Note that this is important for the
-first-pass call when this value is temporarily adjusted to stop at the current
-position. So DO NOT change this to a test for binary zero. */
-
-for (; ptr < cd->end_pattern; ptr++)
- {
- /* Skip over backslashed characters and also entire \Q...\E */
-
- if (*ptr == CHAR_BACKSLASH)
- {
- if (*(++ptr) == CHAR_NULL) goto FAIL_EXIT;
- if (*ptr == CHAR_Q) for (;;)
- {
- while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {};
- if (*ptr == CHAR_NULL) goto FAIL_EXIT;
- if (*(++ptr) == CHAR_E) break;
- }
- continue;
- }
-
- /* Skip over character classes; this logic must be similar to the way they
- are handled for real. If the first character is '^', skip it. Also, if the
- first few characters (either before or after ^) are \Q\E or \E we skip them
- too. This makes for compatibility with Perl. Note the use of STR macros to
- encode "Q\\E" so that it works in UTF-8 on EBCDIC platforms. */
-
- if (*ptr == CHAR_LEFT_SQUARE_BRACKET)
- {
- BOOL negate_class = FALSE;
- for (;;)
- {
- if (ptr[1] == CHAR_BACKSLASH)
- {
- if (ptr[2] == CHAR_E)
- ptr+= 2;
- else if (STRNCMP_UC_C8(ptr + 2,
- STR_Q STR_BACKSLASH STR_E, 3) == 0)
- ptr += 4;
- else
- break;
- }
- else if (!negate_class && ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
- {
- negate_class = TRUE;
- ptr++;
- }
- else break;
- }
-
- /* If the next character is ']', it is a data character that must be
- skipped, except in JavaScript compatibility mode. */
-
- if (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET &&
- (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0)
- ptr++;
-
- while (*(++ptr) != CHAR_RIGHT_SQUARE_BRACKET)
- {
- if (*ptr == CHAR_NULL) return -1;
- if (*ptr == CHAR_BACKSLASH)
- {
- if (*(++ptr) == CHAR_NULL) goto FAIL_EXIT;
- if (*ptr == CHAR_Q) for (;;)
- {
- while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {};
- if (*ptr == CHAR_NULL) goto FAIL_EXIT;
- if (*(++ptr) == CHAR_E) break;
- }
- continue;
- }
- }
- continue;
- }
-
- /* Skip comments in /x mode */
-
- if (xmode && *ptr == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != CHAR_NULL)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- if (*ptr == CHAR_NULL) goto FAIL_EXIT;
- continue;
- }
-
- /* Check for the special metacharacters */
-
- if (*ptr == CHAR_LEFT_PARENTHESIS)
- {
- int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count);
- if (rc > 0) return rc;
- if (*ptr == CHAR_NULL) goto FAIL_EXIT;
- }
-
- else if (*ptr == CHAR_RIGHT_PARENTHESIS)
- {
- if (dup_parens && *count < hwm_count) *count = hwm_count;
- goto FAIL_EXIT;
- }
-
- else if (*ptr == CHAR_VERTICAL_LINE && dup_parens)
- {
- if (*count > hwm_count) hwm_count = *count;
- *count = start_count;
- }
- }
-
-FAIL_EXIT:
-*ptrptr = ptr;
-return -1;
-}
-
-
-
-
-/*************************************************
-* Find forward referenced subpattern *
-*************************************************/
-
-/* This function scans along a pattern's text looking for capturing
-subpatterns, and counting them. If it finds a named pattern that matches the
-name it is given, it returns its number. Alternatively, if the name is NULL, it
-returns when it reaches a given numbered subpattern. This is used for forward
-references to subpatterns. We used to be able to start this scan from the
-current compiling point, using the current count value from cd->bracount, and
-do it all in a single loop, but the addition of the possibility of duplicate
-subpattern numbers means that we have to scan from the very start, in order to
-take account of such duplicates, and to use a recursive function to keep track
-of the different types of group.
-
-Arguments:
- cd compile background data
- 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
- utf TRUE if we are in UTF-8 / UTF-16 / UTF-32 mode
-
-Returns: the number of the found subpattern, or -1 if not found
-*/
-
-static int
-find_parens(compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode,
- BOOL utf)
-{
-pcre_uchar *ptr = (pcre_uchar *)cd->start_pattern;
-int count = 0;
-int rc;
-
-/* If the pattern does not start with an opening parenthesis, the first call
-to find_parens_sub() will scan right to the end (if necessary). However, if it
-does start with a parenthesis, find_parens_sub() will return when it hits the
-matching closing parens. That is why we have to have a loop. */
-
-for (;;)
- {
- rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count);
- if (rc > 0 || *ptr++ == CHAR_NULL) break;
- }
-
-return rc;
-}
-
-
-
-
-/*************************************************
* Find first significant op code *
*************************************************/
@@ -1690,9 +1662,9 @@ for (;;)
case OP_CALLOUT:
case OP_CREF:
- case OP_NCREF:
+ case OP_DNCREF:
case OP_RREF:
- case OP_NRREF:
+ case OP_DNRREF:
case OP_DEF:
code += PRIV(OP_lengths)[*code];
break;
@@ -1706,7 +1678,6 @@ for (;;)
-
/*************************************************
* Find the fixed length of a branch *
*************************************************/
@@ -1830,13 +1801,13 @@ for (;;)
case OP_COMMIT:
case OP_CREF:
case OP_DEF:
+ case OP_DNCREF:
+ case OP_DNRREF:
case OP_DOLL:
case OP_DOLLM:
case OP_EOD:
case OP_EODN:
case OP_FAIL:
- case OP_NCREF:
- case OP_NRREF:
case OP_NOT_WORD_BOUNDARY:
case OP_PRUNE:
case OP_REVERSE:
@@ -1931,16 +1902,20 @@ for (;;)
switch (*cc)
{
- case OP_CRPLUS:
- case OP_CRMINPLUS:
case OP_CRSTAR:
case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ case OP_CRPOSQUERY:
return -1;
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1;
branchlength += (int)GET2(cc,1);
cc += 1 + 2 * IMM2_SIZE;
@@ -2009,6 +1984,8 @@ for (;;)
case OP_QUERYI:
case OP_REF:
case OP_REFI:
+ case OP_DNREF:
+ case OP_DNREFI:
case OP_SBRA:
case OP_SBRAPOS:
case OP_SCBRA:
@@ -2045,7 +2022,6 @@ for (;;)
-
/*************************************************
* Scan compiled regex for specific bracket *
*************************************************/
@@ -2129,9 +2105,6 @@ for (;;)
case OP_MARK:
case OP_PRUNE_ARG:
case OP_SKIP_ARG:
- code += code[1];
- break;
-
case OP_THEN_ARG:
code += code[1];
break;
@@ -2249,9 +2222,6 @@ for (;;)
case OP_MARK:
case OP_PRUNE_ARG:
case OP_SKIP_ARG:
- code += code[1];
- break;
-
case OP_THEN_ARG:
code += code[1];
break;
@@ -2353,15 +2323,23 @@ Arguments:
endcode points to where to stop
utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode
cd contains pointers to tables etc.
+ recurses chain of recurse_check to catch mutual recursion
Returns: TRUE if what is matched could be empty
*/
+typedef struct recurse_check {
+ struct recurse_check *prev;
+ const pcre_uchar *group;
+} recurse_check;
+
static BOOL
could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode,
- BOOL utf, compile_data *cd)
+ BOOL utf, compile_data *cd, recurse_check *recurses)
{
register pcre_uchar c;
+recurse_check this_recurse;
+
for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
code < endcode;
code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE))
@@ -2389,25 +2367,50 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
if (c == OP_RECURSE)
{
- const pcre_uchar *scode;
+ const pcre_uchar *scode = cd->start_code + GET(code, 1);
BOOL empty_branch;
- /* Test for forward reference */
+ /* Test for forward reference or uncompleted reference. This is disabled
+ when called to scan a completed pattern by setting cd->start_workspace to
+ NULL. */
- for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE)
- if ((int)GET(scode, 0) == (int)(code + 1 - cd->start_code)) return TRUE;
+ if (cd->start_workspace != NULL)
+ {
+ const pcre_uchar *tcode;
+ for (tcode = cd->start_workspace; tcode < cd->hwm; tcode += LINK_SIZE)
+ if ((int)GET(tcode, 0) == (int)(code + 1 - cd->start_code)) return TRUE;
+ if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
+ }
- /* Not a forward reference, test for completed backward reference */
+ /* If we are scanning a completed pattern, there are no forward references
+ and all groups are complete. We need to detect whether this is a recursive
+ call, as otherwise there will be an infinite loop. If it is a recursion,
+ just skip over it. Simple recursions are easily detected. For mutual
+ recursions we keep a chain on the stack. */
- empty_branch = FALSE;
- scode = cd->start_code + GET(code, 1);
- if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
+ else
+ {
+ recurse_check *r = recurses;
+ const pcre_uchar *endgroup = scode;
- /* Completed backwards reference */
+ do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
+ if (code >= scode && code <= endgroup) continue; /* Simple recursion */
+
+ for (r = recurses; r != NULL; r = r->prev)
+ if (r->group == scode) break;
+ if (r != NULL) continue; /* Mutual recursion */
+ }
+
+ /* Completed reference; scan the referenced group, remembering it on the
+ stack chain to detect mutual recursions. */
+
+ empty_branch = FALSE;
+ this_recurse.prev = recurses;
+ this_recurse.group = scode;
do
{
- if (could_be_empty_branch(scode, endcode, utf, cd))
+ if (could_be_empty_branch(scode, endcode, utf, cd, &this_recurse))
{
empty_branch = TRUE;
break;
@@ -2463,7 +2466,7 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
empty_branch = FALSE;
do
{
- if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd))
+ if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd, NULL))
empty_branch = TRUE;
code += GET(code, 1);
}
@@ -2505,15 +2508,19 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
case OP_CRMINSTAR:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
break;
default: /* Non-repeat => class must match */
case OP_CRPLUS: /* These repeats aren't empty */
case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
return FALSE;
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */
break;
}
@@ -2521,34 +2528,57 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
/* Opcodes that must match a character */
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+
case OP_PROP:
case OP_NOTPROP:
+ case OP_ANYNL:
+
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
case OP_EXTUNI:
+
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_CHAR:
case OP_CHARI:
case OP_NOT:
case OP_NOTI:
+
case OP_PLUS:
+ case OP_PLUSI:
case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_EXACT:
+ case OP_MINPLUSI:
+
case OP_NOTPLUS:
+ case OP_NOTPLUSI:
case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+
+ case OP_EXACT:
+ case OP_EXACTI:
case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+
case OP_TYPEPLUS:
case OP_TYPEMINPLUS:
case OP_TYPEPOSPLUS:
case OP_TYPEEXACT:
+
return FALSE;
/* These are going to continue, as they may be empty, but we have to
@@ -2582,30 +2612,58 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
return TRUE;
/* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO,
- MINUPTO, and POSUPTO may be followed by a multibyte character */
+ MINUPTO, and POSUPTO and their caseless and negative versions may be
+ followed by a multibyte character. */
#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
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:
+ case OP_NOTPOSQUERYI:
+
if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]);
break;
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:
+
if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]);
break;
#endif
@@ -2616,9 +2674,6 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
case OP_MARK:
case OP_PRUNE_ARG:
case OP_SKIP_ARG:
- code += code[1];
- break;
-
case OP_THEN_ARG:
code += code[1];
break;
@@ -2662,7 +2717,7 @@ could_be_empty(const pcre_uchar *code, const pcre_uchar *endcode,
{
while (bcptr != NULL && bcptr->current_branch >= code)
{
- if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd))
+ if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd, NULL))
return FALSE;
bcptr = bcptr->outer;
}
@@ -2672,6 +2727,1072 @@ return TRUE;
/*************************************************
+* Base opcode of repeated opcodes *
+*************************************************/
+
+/* Returns the base opcode for repeated single character type opcodes. If the
+opcode is not a repeated character type, it returns with the original value.
+
+Arguments: c opcode
+Returns: base opcode for the type
+*/
+
+static pcre_uchar
+get_repeat_base(pcre_uchar c)
+{
+return (c > OP_TYPEPOSUPTO)? c :
+ (c >= OP_TYPESTAR)? OP_TYPESTAR :
+ (c >= OP_NOTSTARI)? OP_NOTSTARI :
+ (c >= OP_NOTSTAR)? OP_NOTSTAR :
+ (c >= OP_STARI)? OP_STARI :
+ OP_STAR;
+}
+
+
+
+#ifdef SUPPORT_UCP
+/*************************************************
+* Check a character and a property *
+*************************************************/
+
+/* This function is called by check_auto_possessive() when a property item
+is adjacent to a fixed character.
+
+Arguments:
+ c the character
+ ptype the property type
+ pdata the data for the type
+ negated TRUE if it's a negated property (\P or \p{^)
+
+Returns: TRUE if auto-possessifying is OK
+*/
+
+static BOOL
+check_char_prop(pcre_uint32 c, unsigned int ptype, unsigned int pdata,
+ BOOL negated)
+{
+const pcre_uint32 *p;
+const ucd_record *prop = GET_UCD(c);
+
+switch(ptype)
+ {
+ case PT_LAMP:
+ return (prop->chartype == ucp_Lu ||
+ prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt) == negated;
+
+ case PT_GC:
+ return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated;
+
+ case PT_PC:
+ return (pdata == prop->chartype) == negated;
+
+ case PT_SC:
+ return (pdata == prop->script) == negated;
+
+ /* These are specials */
+
+ case PT_ALNUM:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated;
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included, which
+ means that Perl space and POSIX space are now identical. PCRE was changed
+ at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ return negated;
+
+ default:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated;
+ }
+ break; /* Control never reaches here */
+
+ case PT_WORD:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE) == negated;
+
+ case PT_CLIST:
+ p = PRIV(ucd_caseless_sets) + prop->caseset;
+ for (;;)
+ {
+ if (c < *p) return !negated;
+ if (c == *p++) return negated;
+ }
+ break; /* Control never reaches here */
+ }
+
+return FALSE;
+}
+#endif /* SUPPORT_UCP */
+
+
+
+/*************************************************
+* Fill the character property list *
+*************************************************/
+
+/* Checks whether the code points to an opcode that can take part in auto-
+possessification, and if so, fills a list with its properties.
+
+Arguments:
+ code points to start of expression
+ utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode
+ fcc points to case-flipping table
+ list points to output list
+ list[0] will be filled with the opcode
+ list[1] will be non-zero if this opcode
+ can match an empty character string
+ list[2..7] depends on the opcode
+
+Returns: points to the start of the next opcode if *code is accepted
+ NULL if *code is not accepted
+*/
+
+static const pcre_uchar *
+get_chr_property_list(const pcre_uchar *code, BOOL utf,
+ const pcre_uint8 *fcc, pcre_uint32 *list)
+{
+pcre_uchar c = *code;
+pcre_uchar base;
+const pcre_uchar *end;
+pcre_uint32 chr;
+
+#ifdef SUPPORT_UCP
+pcre_uint32 *clist_dest;
+const pcre_uint32 *clist_src;
+#else
+utf = utf; /* Suppress "unused parameter" compiler warning */
+#endif
+
+list[0] = c;
+list[1] = FALSE;
+code++;
+
+if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
+ {
+ base = get_repeat_base(c);
+ c -= (base - OP_STAR);
+
+ if (c == OP_UPTO || c == OP_MINUPTO || c == OP_EXACT || c == OP_POSUPTO)
+ code += IMM2_SIZE;
+
+ list[1] = (c != OP_PLUS && c != OP_MINPLUS && c != OP_EXACT && c != OP_POSPLUS);
+
+ switch(base)
+ {
+ case OP_STAR:
+ list[0] = OP_CHAR;
+ break;
+
+ case OP_STARI:
+ list[0] = OP_CHARI;
+ break;
+
+ case OP_NOTSTAR:
+ list[0] = OP_NOT;
+ break;
+
+ case OP_NOTSTARI:
+ list[0] = OP_NOTI;
+ break;
+
+ case OP_TYPESTAR:
+ list[0] = *code;
+ code++;
+ break;
+ }
+ c = list[0];
+ }
+
+switch(c)
+ {
+ 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_DOLL:
+ case OP_DOLLM:
+ return code;
+
+ case OP_CHAR:
+ case OP_NOT:
+ GETCHARINCTEST(chr, code);
+ list[2] = chr;
+ list[3] = NOTACHAR;
+ return code;
+
+ case OP_CHARI:
+ case OP_NOTI:
+ list[0] = (c == OP_CHARI) ? OP_CHAR : OP_NOT;
+ GETCHARINCTEST(chr, code);
+ list[2] = chr;
+
+#ifdef SUPPORT_UCP
+ if (chr < 128 || (chr < 256 && !utf))
+ list[3] = fcc[chr];
+ else
+ list[3] = UCD_OTHERCASE(chr);
+#elif defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ list[3] = (chr < 256) ? fcc[chr] : chr;
+#else
+ list[3] = fcc[chr];
+#endif
+
+ /* The othercase might be the same value. */
+
+ if (chr == list[3])
+ list[3] = NOTACHAR;
+ else
+ list[4] = NOTACHAR;
+ return code;
+
+#ifdef SUPPORT_UCP
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (code[0] != PT_CLIST)
+ {
+ list[2] = code[0];
+ list[3] = code[1];
+ return code + 2;
+ }
+
+ /* Convert only if we have enough space. */
+
+ clist_src = PRIV(ucd_caseless_sets) + code[1];
+ clist_dest = list + 2;
+ code += 2;
+
+ do {
+ if (clist_dest >= list + 8)
+ {
+ /* Early return if there is not enough space. This should never
+ happen, since all clists are shorter than 5 character now. */
+ list[2] = code[0];
+ list[3] = code[1];
+ return code;
+ }
+ *clist_dest++ = *clist_src;
+ }
+ while(*clist_src++ != NOTACHAR);
+
+ /* All characters are stored. The terminating NOTACHAR
+ is copied form the clist itself. */
+
+ list[0] = (c == OP_PROP) ? OP_CHAR : OP_NOT;
+ return code;
+#endif
+
+ case OP_NCLASS:
+ case OP_CLASS:
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ if (c == OP_XCLASS)
+ end = code + GET(code, 0) - 1;
+ else
+#endif
+ end = code + 32 / sizeof(pcre_uchar);
+
+ switch(*end)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
+ list[1] = TRUE;
+ end++;
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
+ end++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ list[1] = (GET2(end, 1) == 0);
+ end += 1 + 2 * IMM2_SIZE;
+ break;
+ }
+ list[2] = end - code;
+ return end;
+ }
+return NULL; /* Opcode not accepted */
+}
+
+
+
+/*************************************************
+* Scan further character sets for match *
+*************************************************/
+
+/* Checks whether the base and the current opcode have a common character, in
+which case the base cannot be possessified.
+
+Arguments:
+ code points to the byte code
+ utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
+ cd static compile data
+ base_list the data list of the base opcode
+
+Returns: TRUE if the auto-possessification is possible
+*/
+
+static BOOL
+compare_opcodes(const pcre_uchar *code, BOOL utf, const compile_data *cd,
+ const pcre_uint32 *base_list, const pcre_uchar *base_end)
+{
+pcre_uchar c;
+pcre_uint32 list[8];
+const pcre_uint32 *chr_ptr;
+const pcre_uint32 *ochr_ptr;
+const pcre_uint32 *list_ptr;
+const pcre_uchar *next_code;
+const pcre_uint8 *class_bitset;
+const pcre_uint32 *set1, *set2, *set_end;
+pcre_uint32 chr;
+BOOL accepted, invert_bits;
+
+/* Note: the base_list[1] contains whether the current opcode has greedy
+(represented by a non-zero value) quantifier. This is a different from
+other character type lists, which stores here that the character iterator
+matches to an empty string (also represented by a non-zero value). */
+
+for(;;)
+ {
+ /* All operations move the code pointer forward.
+ Therefore infinite recursions are not possible. */
+
+ c = *code;
+
+ /* Skip over callouts */
+
+ if (c == OP_CALLOUT)
+ {
+ code += PRIV(OP_lengths)[c];
+ continue;
+ }
+
+ if (c == OP_ALT)
+ {
+ do code += GET(code, 1); while (*code == OP_ALT);
+ c = *code;
+ }
+
+ switch(c)
+ {
+ case OP_END:
+ case OP_KETRPOS:
+ /* TRUE only in greedy case. The non-greedy case could be replaced by
+ an OP_EXACT, but it is probably not worth it. (And note that OP_EXACT
+ uses more memory, which we cannot get at this stage.) */
+
+ return base_list[1] != 0;
+
+ case OP_KET:
+ /* If the bracket is capturing, and referenced by an OP_RECURSE, or
+ it is an atomic sub-pattern (assert, once, etc.) the non-greedy case
+ cannot be converted to a possessive form. */
+
+ if (base_list[1] == 0) return FALSE;
+
+ switch(*(code - GET(code, 1)))
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ /* Atomic sub-patterns and assertions can always auto-possessify their
+ last iterator. */
+ return TRUE;
+ }
+
+ code += PRIV(OP_lengths)[c];
+ continue;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ next_code = code + GET(code, 1);
+ code += PRIV(OP_lengths)[c];
+
+ while (*next_code == OP_ALT)
+ {
+ if (!compare_opcodes(code, utf, cd, base_list, base_end)) return FALSE;
+ code = next_code + 1 + LINK_SIZE;
+ next_code += GET(next_code, 1);
+ }
+ continue;
+
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+
+ next_code = code + 1;
+ if (*next_code != OP_BRA && *next_code != OP_CBRA
+ && *next_code != OP_ONCE && *next_code != OP_ONCE_NC) return FALSE;
+
+ do next_code += GET(next_code, 1); while (*next_code == OP_ALT);
+
+ /* The bracket content will be checked by the
+ OP_BRA/OP_CBRA case above. */
+ next_code += 1 + LINK_SIZE;
+ if (!compare_opcodes(next_code, utf, cd, base_list, base_end))
+ return FALSE;
+
+ code += PRIV(OP_lengths)[c];
+ continue;
+ }
+
+ /* Check for a supported opcode, and load its properties. */
+
+ code = get_chr_property_list(code, utf, cd->fcc, list);
+ if (code == NULL) return FALSE; /* Unsupported */
+
+ /* If either opcode is a small character list, set pointers for comparing
+ characters from that list with another list, or with a property. */
+
+ if (base_list[0] == OP_CHAR)
+ {
+ chr_ptr = base_list + 2;
+ list_ptr = list;
+ }
+ else if (list[0] == OP_CHAR)
+ {
+ chr_ptr = list + 2;
+ list_ptr = base_list;
+ }
+
+ /* Character bitsets can also be compared to certain opcodes. */
+
+ else if (base_list[0] == OP_CLASS || list[0] == OP_CLASS
+#ifdef COMPILE_PCRE8
+ /* In 8 bit, non-UTF mode, OP_CLASS and OP_NCLASS are the same. */
+ || (!utf && (base_list[0] == OP_NCLASS || list[0] == OP_NCLASS))
+#endif
+ )
+ {
+#ifdef COMPILE_PCRE8
+ if (base_list[0] == OP_CLASS || (!utf && base_list[0] == OP_NCLASS))
+#else
+ if (base_list[0] == OP_CLASS)
+#endif
+ {
+ set1 = (pcre_uint32 *)(base_end - base_list[2]);
+ list_ptr = list;
+ }
+ else
+ {
+ set1 = (pcre_uint32 *)(code - list[2]);
+ list_ptr = base_list;
+ }
+
+ invert_bits = FALSE;
+ switch(list_ptr[0])
+ {
+ case OP_CLASS:
+ case OP_NCLASS:
+ set2 = (pcre_uint32 *)
+ ((list_ptr == list ? code : base_end) - list_ptr[2]);
+ break;
+
+ /* OP_XCLASS cannot be supported here, because its bitset
+ is not necessarily complete. E.g: [a-\0x{200}] is stored
+ as a character range, and the appropriate bits are not set. */
+
+ case OP_NOT_DIGIT:
+ invert_bits = TRUE;
+ /* Fall through */
+ case OP_DIGIT:
+ set2 = (pcre_uint32 *)(cd->cbits + cbit_digit);
+ break;
+
+ case OP_NOT_WHITESPACE:
+ invert_bits = TRUE;
+ /* Fall through */
+ case OP_WHITESPACE:
+ set2 = (pcre_uint32 *)(cd->cbits + cbit_space);
+ break;
+
+ case OP_NOT_WORDCHAR:
+ invert_bits = TRUE;
+ /* Fall through */
+ case OP_WORDCHAR:
+ set2 = (pcre_uint32 *)(cd->cbits + cbit_word);
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ /* Compare 4 bytes to improve speed. */
+ set_end = set1 + (32 / 4);
+ if (invert_bits)
+ {
+ do
+ {
+ if ((*set1++ & ~(*set2++)) != 0) return FALSE;
+ }
+ while (set1 < set_end);
+ }
+ else
+ {
+ do
+ {
+ if ((*set1++ & *set2++) != 0) return FALSE;
+ }
+ while (set1 < set_end);
+ }
+
+ if (list[1] == 0) return TRUE;
+ /* Might be an empty repeat. */
+ continue;
+ }
+
+ /* Some property combinations also acceptable. Unicode property opcodes are
+ processed specially; the rest can be handled with a lookup table. */
+
+ else
+ {
+ pcre_uint32 leftop, rightop;
+
+ leftop = base_list[0];
+ rightop = list[0];
+
+#ifdef SUPPORT_UCP
+ accepted = FALSE; /* Always set in non-unicode case. */
+ if (leftop == OP_PROP || leftop == OP_NOTPROP)
+ {
+ if (rightop == OP_EOD)
+ accepted = TRUE;
+ else if (rightop == OP_PROP || rightop == OP_NOTPROP)
+ {
+ int n;
+ const pcre_uint8 *p;
+ BOOL same = leftop == rightop;
+ BOOL lisprop = leftop == OP_PROP;
+ BOOL risprop = rightop == OP_PROP;
+ BOOL bothprop = lisprop && risprop;
+
+ /* There's a table that specifies how each combination is to be
+ processed:
+ 0 Always return FALSE (never auto-possessify)
+ 1 Character groups are distinct (possessify if both are OP_PROP)
+ 2 Check character categories in the same group (general or particular)
+ 3 Return TRUE if the two opcodes are not the same
+ ... see comments below
+ */
+
+ n = propposstab[base_list[2]][list[2]];
+ switch(n)
+ {
+ case 0: break;
+ case 1: accepted = bothprop; break;
+ case 2: accepted = (base_list[3] == list[3]) != same; break;
+ case 3: accepted = !same; break;
+
+ case 4: /* Left general category, right particular category */
+ accepted = risprop && catposstab[base_list[3]][list[3]] == same;
+ break;
+
+ case 5: /* Right general category, left particular category */
+ accepted = lisprop && catposstab[list[3]][base_list[3]] == same;
+ break;
+
+ /* This code is logically tricky. Think hard before fiddling with it.
+ The posspropstab table has four entries per row. Each row relates to
+ one of PCRE's special properties such as ALNUM or SPACE or WORD.
+ Only WORD actually needs all four entries, but using repeats for the
+ others means they can all use the same code below.
+
+ The first two entries in each row are Unicode general categories, and
+ apply always, because all the characters they include are part of the
+ PCRE character set. The third and fourth entries are a general and a
+ particular category, respectively, that include one or more relevant
+ characters. One or the other is used, depending on whether the check
+ is for a general or a particular category. However, in both cases the
+ category contains more characters than the specials that are defined
+ for the property being tested against. Therefore, it cannot be used
+ in a NOTPROP case.
+
+ Example: the row for WORD contains ucp_L, ucp_N, ucp_P, ucp_Po.
+ Underscore is covered by ucp_P or ucp_Po. */
+
+ case 6: /* Left alphanum vs right general category */
+ case 7: /* Left space vs right general category */
+ case 8: /* Left word vs right general category */
+ p = posspropstab[n-6];
+ accepted = risprop && lisprop ==
+ (list[3] != p[0] &&
+ list[3] != p[1] &&
+ (list[3] != p[2] || !lisprop));
+ break;
+
+ case 9: /* Right alphanum vs left general category */
+ case 10: /* Right space vs left general category */
+ case 11: /* Right word vs left general category */
+ p = posspropstab[n-9];
+ accepted = lisprop && risprop ==
+ (base_list[3] != p[0] &&
+ base_list[3] != p[1] &&
+ (base_list[3] != p[2] || !risprop));
+ break;
+
+ case 12: /* Left alphanum vs right particular category */
+ case 13: /* Left space vs right particular category */
+ case 14: /* Left word vs right particular category */
+ p = posspropstab[n-12];
+ accepted = risprop && lisprop ==
+ (catposstab[p[0]][list[3]] &&
+ catposstab[p[1]][list[3]] &&
+ (list[3] != p[3] || !lisprop));
+ break;
+
+ case 15: /* Right alphanum vs left particular category */
+ case 16: /* Right space vs left particular category */
+ case 17: /* Right word vs left particular category */
+ p = posspropstab[n-15];
+ accepted = lisprop && risprop ==
+ (catposstab[p[0]][base_list[3]] &&
+ catposstab[p[1]][base_list[3]] &&
+ (base_list[3] != p[3] || !risprop));
+ break;
+ }
+ }
+ }
+
+ else
+#endif /* SUPPORT_UCP */
+
+ accepted = leftop >= FIRST_AUTOTAB_OP && leftop <= LAST_AUTOTAB_LEFT_OP &&
+ rightop >= FIRST_AUTOTAB_OP && rightop <= LAST_AUTOTAB_RIGHT_OP &&
+ autoposstab[leftop - FIRST_AUTOTAB_OP][rightop - FIRST_AUTOTAB_OP];
+
+ if (!accepted)
+ return FALSE;
+
+ if (list[1] == 0) return TRUE;
+ /* Might be an empty repeat. */
+ continue;
+ }
+
+ /* Control reaches here only if one of the items is a small character list.
+ All characters are checked against the other side. */
+
+ do
+ {
+ chr = *chr_ptr;
+
+ switch(list_ptr[0])
+ {
+ case OP_CHAR:
+ ochr_ptr = list_ptr + 2;
+ do
+ {
+ if (chr == *ochr_ptr) return FALSE;
+ ochr_ptr++;
+ }
+ while(*ochr_ptr != NOTACHAR);
+ break;
+
+ case OP_NOT:
+ ochr_ptr = list_ptr + 2;
+ do
+ {
+ if (chr == *ochr_ptr)
+ break;
+ ochr_ptr++;
+ }
+ while(*ochr_ptr != NOTACHAR);
+ if (*ochr_ptr == NOTACHAR) return FALSE; /* Not found */
+ break;
+
+ /* 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:
+ if (chr < 256 && (cd->ctypes[chr] & ctype_digit) != 0) return FALSE;
+ break;
+
+ case OP_NOT_DIGIT:
+ if (chr > 255 || (cd->ctypes[chr] & ctype_digit) == 0) return FALSE;
+ break;
+
+ case OP_WHITESPACE:
+ if (chr < 256 && (cd->ctypes[chr] & ctype_space) != 0) return FALSE;
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (chr > 255 || (cd->ctypes[chr] & ctype_space) == 0) return FALSE;
+ break;
+
+ case OP_WORDCHAR:
+ if (chr < 255 && (cd->ctypes[chr] & ctype_word) != 0) return FALSE;
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (chr > 255 || (cd->ctypes[chr] & ctype_word) == 0) return FALSE;
+ break;
+
+ case OP_HSPACE:
+ switch(chr)
+ {
+ HSPACE_CASES: return FALSE;
+ default: break;
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ switch(chr)
+ {
+ HSPACE_CASES: break;
+ default: return FALSE;
+ }
+ break;
+
+ case OP_ANYNL:
+ case OP_VSPACE:
+ switch(chr)
+ {
+ VSPACE_CASES: return FALSE;
+ default: break;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ switch(chr)
+ {
+ VSPACE_CASES: break;
+ default: return FALSE;
+ }
+ break;
+
+ case OP_DOLL:
+ case OP_EODN:
+ switch (chr)
+ {
+ case CHAR_CR:
+ case CHAR_LF:
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#ifndef EBCDIC
+ case 0x2028:
+ case 0x2029:
+#endif /* Not EBCDIC */
+ return FALSE;
+ }
+ break;
+
+ case OP_EOD: /* Can always possessify before \z */
+ break;
+
+#ifdef SUPPORT_UCP
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (!check_char_prop(chr, list_ptr[2], list_ptr[3],
+ list_ptr[0] == OP_NOTPROP))
+ return FALSE;
+ break;
+#endif
+
+ case OP_NCLASS:
+ if (chr > 255) return FALSE;
+ /* Fall through */
+
+ case OP_CLASS:
+ if (chr > 255) break;
+ class_bitset = (pcre_uint8 *)
+ ((list_ptr == list ? code : base_end) - list_ptr[2]);
+ if ((class_bitset[chr >> 3] & (1 << (chr & 7))) != 0) return FALSE;
+ break;
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ if (PRIV(xclass)(chr, (list_ptr == list ? code : base_end) -
+ list_ptr[2] + LINK_SIZE, utf)) return FALSE;
+ break;
+#endif
+
+ default:
+ return FALSE;
+ }
+
+ chr_ptr++;
+ }
+ while(*chr_ptr != NOTACHAR);
+
+ /* At least one character must be matched from this opcode. */
+
+ if (list[1] == 0) return TRUE;
+ }
+
+return FALSE;
+}
+
+
+
+/*************************************************
+* Scan compiled regex for auto-possession *
+*************************************************/
+
+/* Replaces single character iterations with their possessive alternatives
+if appropriate. This function modifies the compiled opcode!
+
+Arguments:
+ code points to start of the byte code
+ utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
+ cd static compile data
+
+Returns: nothing
+*/
+
+static void
+auto_possessify(pcre_uchar *code, BOOL utf, const compile_data *cd)
+{
+register pcre_uchar c;
+const pcre_uchar *end;
+pcre_uchar *repeat_opcode;
+pcre_uint32 list[8];
+
+for (;;)
+ {
+ c = *code;
+
+ if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
+ {
+ c -= get_repeat_base(c) - OP_STAR;
+ end = (c <= OP_MINUPTO) ?
+ get_chr_property_list(code, utf, cd->fcc, list) : NULL;
+ list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;
+
+ if (end != NULL && compare_opcodes(end, utf, cd, list, end))
+ {
+ switch(c)
+ {
+ case OP_STAR:
+ *code += OP_POSSTAR - OP_STAR;
+ break;
+
+ case OP_MINSTAR:
+ *code += OP_POSSTAR - OP_MINSTAR;
+ break;
+
+ case OP_PLUS:
+ *code += OP_POSPLUS - OP_PLUS;
+ break;
+
+ case OP_MINPLUS:
+ *code += OP_POSPLUS - OP_MINPLUS;
+ break;
+
+ case OP_QUERY:
+ *code += OP_POSQUERY - OP_QUERY;
+ break;
+
+ case OP_MINQUERY:
+ *code += OP_POSQUERY - OP_MINQUERY;
+ break;
+
+ case OP_UPTO:
+ *code += OP_POSUPTO - OP_UPTO;
+ break;
+
+ case OP_MINUPTO:
+ *code += OP_MINUPTO - OP_UPTO;
+ break;
+ }
+ }
+ c = *code;
+ }
+ else if (c == OP_CLASS || c == OP_NCLASS || c == OP_XCLASS)
+ {
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ if (c == OP_XCLASS)
+ repeat_opcode = code + GET(code, 1);
+ else
+#endif
+ repeat_opcode = code + 1 + (32 / sizeof(pcre_uchar));
+
+ c = *repeat_opcode;
+ if (c >= OP_CRSTAR && c <= OP_CRMINRANGE)
+ {
+ /* end must not be NULL. */
+ end = get_chr_property_list(code, utf, cd->fcc, list);
+
+ list[1] = (c & 1) == 0;
+
+ if (compare_opcodes(end, utf, cd, list, end))
+ {
+ switch (c)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ *repeat_opcode = OP_CRPOSSTAR;
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ *repeat_opcode = OP_CRPOSPLUS;
+ break;
+
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ *repeat_opcode = OP_CRPOSQUERY;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ *repeat_opcode = OP_CRPOSRANGE;
+ break;
+ }
+ }
+ }
+ c = *code;
+ }
+
+ switch(c)
+ {
+ case OP_END:
+ return;
+
+ 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:
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSUPTO:
+ if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
+ code += 2;
+ break;
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ code += GET(code, 1);
+ break;
+#endif
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ code += code[1];
+ break;
+ }
+
+ /* Add in the fixed length from the table */
+
+ 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. */
+
+#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
+ if (utf) switch(c)
+ {
+ 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 (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
+ break;
+ }
+#else
+ (void)(utf); /* Keep compiler happy by referencing function argument */
+#endif
+ }
+}
+
+
+
+/*************************************************
* Check for POSIX class syntax *
*************************************************/
@@ -2692,7 +3813,7 @@ class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
below handles the special case of \], but does not try to do any other escape
processing. This makes it different from Perl for cases such as [:l\ower:]
where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize
-"l\ower". This is a lesser evil that not diagnosing bad classes when Perl does,
+"l\ower". This is a lesser evil than not diagnosing bad classes when Perl does,
I think.
A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
@@ -2954,476 +4075,11 @@ for (++c; c <= d; c++)
*cptr = c; /* Rest of input range */
return 0;
}
-
-
-
-/*************************************************
-* Check a character and a property *
-*************************************************/
-
-/* This function is called by check_auto_possessive() when a property item
-is adjacent to a fixed character.
-
-Arguments:
- c the character
- ptype the property type
- pdata the data for the type
- negated TRUE if it's a negated property (\P or \p{^)
-
-Returns: TRUE if auto-possessifying is OK
-*/
-
-static BOOL
-check_char_prop(pcre_uint32 c, unsigned int ptype, unsigned int pdata, BOOL negated)
-{
-#ifdef SUPPORT_UCP
-const pcre_uint32 *p;
-#endif
-
-const ucd_record *prop = GET_UCD(c);
-
-switch(ptype)
- {
- case PT_LAMP:
- return (prop->chartype == ucp_Lu ||
- prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt) == negated;
-
- case PT_GC:
- return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated;
-
- case PT_PC:
- return (pdata == prop->chartype) == negated;
-
- case PT_SC:
- return (pdata == prop->script) == negated;
-
- /* These are specials */
-
- case PT_ALNUM:
- return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated;
-
- case PT_SPACE: /* Perl space */
- 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 (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 (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
- c == CHAR_UNDERSCORE) == negated;
-
-#ifdef SUPPORT_UCP
- case PT_CLIST:
- p = PRIV(ucd_caseless_sets) + prop->caseset;
- for (;;)
- {
- if (c < *p) return !negated;
- if (c == *p++) return negated;
- }
- break; /* Control never reaches here */
-#endif
- }
-
-return FALSE;
-}
#endif /* SUPPORT_UCP */
/*************************************************
-* Check if auto-possessifying is possible *
-*************************************************/
-
-/* This function is called for unlimited repeats of certain items, to see
-whether the next thing could possibly match the repeated item. If not, it makes
-sense to automatically possessify the repeated item.
-
-Arguments:
- previous pointer to the repeated opcode
- utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
- ptr next character in pattern
- options options bits
- cd contains pointers to tables etc.
-
-Returns: TRUE if possessifying is wanted
-*/
-
-static BOOL
-check_auto_possessive(const pcre_uchar *previous, BOOL utf,
- const pcre_uchar *ptr, int options, compile_data *cd)
-{
-pcre_uint32 c = NOTACHAR;
-pcre_uint32 next;
-int escape;
-pcre_uchar op_code = *previous++;
-
-/* Skip whitespace and comments in extended mode */
-
-if ((options & PCRE_EXTENDED) != 0)
- {
- for (;;)
- {
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
- if (*ptr == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != CHAR_NULL)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- }
- else break;
- }
- }
-
-/* If the next item is one that we can handle, get its value. A non-negative
-value is a character, a negative value is an escape value. */
-
-if (*ptr == CHAR_BACKSLASH)
- {
- int temperrorcode = 0;
- escape = check_escape(&ptr, &next, &temperrorcode, cd->bracount, options, FALSE);
- if (temperrorcode != 0) return FALSE;
- ptr++; /* Point after the escape sequence */
- }
-else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0)
- {
- escape = 0;
-#ifdef SUPPORT_UTF
- if (utf) { GETCHARINC(next, ptr); } else
-#endif
- next = *ptr++;
- }
-else return FALSE;
-
-/* Skip whitespace and comments in extended mode */
-
-if ((options & PCRE_EXTENDED) != 0)
- {
- for (;;)
- {
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
- if (*ptr == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != CHAR_NULL)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- }
- else break;
- }
- }
-
-/* If the next thing is itself optional, we have to give up. */
-
-if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
- STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
- return FALSE;
-
-/* If the previous item is a character, get its value. */
-
-if (op_code == OP_CHAR || op_code == OP_CHARI ||
- op_code == OP_NOT || op_code == OP_NOTI)
- {
-#ifdef SUPPORT_UTF
- GETCHARTEST(c, previous);
-#else
- c = *previous;
-#endif
- }
-
-/* Now compare the next item with the previous opcode. First, handle cases when
-the next item is a character. */
-
-if (escape == 0)
- {
- /* For a caseless UTF match, the next character may have more than one other
- case, which maps to the special PT_CLIST property. Check this first. */
-
-#ifdef SUPPORT_UCP
- if (utf && c != NOTACHAR && (options & PCRE_CASELESS) != 0)
- {
- unsigned int ocs = UCD_CASESET(next);
- if (ocs > 0) return check_char_prop(c, PT_CLIST, ocs, op_code >= OP_NOT);
- }
-#endif
-
- switch(op_code)
- {
- case OP_CHAR:
- return c != next;
-
- /* 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. We know that next can have only one other case,
- because multi-other-case characters are dealt with above. */
-
- case OP_CHARI:
- if (c == next) return FALSE;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- pcre_uint32 othercase;
- if (next < 128) othercase = cd->fcc[next]; else
-#ifdef SUPPORT_UCP
- othercase = UCD_OTHERCASE(next);
-#else
- othercase = NOTACHAR;
-#endif
- return c != othercase;
- }
- else
-#endif /* SUPPORT_UTF */
- return (c != TABLE_GET(next, cd->fcc, next)); /* Not UTF */
-
- case OP_NOT:
- return c == next;
-
- case OP_NOTI:
- if (c == next) return TRUE;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- pcre_uint32 othercase;
- if (next < 128) othercase = cd->fcc[next]; else
-#ifdef SUPPORT_UCP
- othercase = UCD_OTHERCASE(next);
-#else
- othercase = NOTACHAR;
-#endif
- return c == othercase;
- }
- else
-#endif /* SUPPORT_UTF */
- return (c == TABLE_GET(next, cd->fcc, next)); /* Not UTF */
-
- /* 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 > 255 || (cd->ctypes[next] & ctype_digit) == 0;
-
- case OP_NOT_DIGIT:
- return next <= 255 && (cd->ctypes[next] & ctype_digit) != 0;
-
- case OP_WHITESPACE:
- return next > 255 || (cd->ctypes[next] & ctype_space) == 0;
-
- case OP_NOT_WHITESPACE:
- return next <= 255 && (cd->ctypes[next] & ctype_space) != 0;
-
- case OP_WORDCHAR:
- return next > 255 || (cd->ctypes[next] & ctype_word) == 0;
-
- case OP_NOT_WORDCHAR:
- return next <= 255 && (cd->ctypes[next] & ctype_word) != 0;
-
- case OP_HSPACE:
- case OP_NOT_HSPACE:
- switch(next)
- {
- HSPACE_CASES:
- return op_code == OP_NOT_HSPACE;
-
- default:
- return op_code != OP_NOT_HSPACE;
- }
-
- case OP_ANYNL:
- case OP_VSPACE:
- case OP_NOT_VSPACE:
- switch(next)
- {
- VSPACE_CASES:
- return op_code == OP_NOT_VSPACE;
-
- default:
- return op_code != OP_NOT_VSPACE;
- }
-
-#ifdef SUPPORT_UCP
- case OP_PROP:
- return check_char_prop(next, previous[0], previous[1], FALSE);
-
- case OP_NOTPROP:
- return check_char_prop(next, previous[0], previous[1], TRUE);
-#endif
-
- default:
- return FALSE;
- }
- }
-
-/* Handle the case when the next item is \d, \s, etc. Note that when PCRE_UCP
-is set, \d turns into ESC_du rather than ESC_d, etc., so ESC_d etc. are
-generated only when PCRE_UCP is *not* set, that is, when only ASCII
-characteristics are recognized. Similarly, the opcodes OP_DIGIT etc. are
-replaced by OP_PROP codes when PCRE_UCP is set. */
-
-switch(op_code)
- {
- case OP_CHAR:
- case OP_CHARI:
- switch(escape)
- {
- case ESC_d:
- return c > 255 || (cd->ctypes[c] & ctype_digit) == 0;
-
- case ESC_D:
- return c <= 255 && (cd->ctypes[c] & ctype_digit) != 0;
-
- case ESC_s:
- return c > 255 || (cd->ctypes[c] & ctype_space) == 0;
-
- case ESC_S:
- return c <= 255 && (cd->ctypes[c] & ctype_space) != 0;
-
- case ESC_w:
- return c > 255 || (cd->ctypes[c] & ctype_word) == 0;
-
- case ESC_W:
- return c <= 255 && (cd->ctypes[c] & ctype_word) != 0;
-
- case ESC_h:
- case ESC_H:
- switch(c)
- {
- HSPACE_CASES:
- return escape != ESC_h;
-
- default:
- return escape == ESC_h;
- }
-
- case ESC_v:
- case ESC_V:
- switch(c)
- {
- VSPACE_CASES:
- return escape != ESC_v;
-
- default:
- return escape == ESC_v;
- }
-
- /* When PCRE_UCP is set, these values get generated for \d etc. Find
- their substitutions and process them. The result will always be either
- ESC_p or ESC_P. Then fall through to process those values. */
-
-#ifdef SUPPORT_UCP
- case ESC_du:
- case ESC_DU:
- case ESC_wu:
- case ESC_WU:
- case ESC_su:
- case ESC_SU:
- {
- int temperrorcode = 0;
- ptr = substitutes[escape - ESC_DU];
- escape = check_escape(&ptr, &next, &temperrorcode, 0, options, FALSE);
- if (temperrorcode != 0) return FALSE;
- ptr++; /* For compatibility */
- }
- /* Fall through */
-
- case ESC_p:
- case ESC_P:
- {
- unsigned int ptype = 0, pdata = 0;
- int errorcodeptr;
- BOOL negated;
-
- ptr--; /* Make ptr point at the p or P */
- if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcodeptr))
- return FALSE;
- ptr++; /* Point past the final curly ket */
-
- /* If the property item is optional, we have to give up. (When generated
- from \d etc by PCRE_UCP, this test will have been applied much earlier,
- to the original \d etc. At this point, ptr will point to a zero byte. */
-
- if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
- STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
- return FALSE;
-
- /* Do the property check. */
-
- return check_char_prop(c, ptype, pdata, (escape == ESC_P) != negated);
- }
-#endif
-
- default:
- return FALSE;
- }
-
- /* In principle, support for Unicode properties should be integrated here as
- well. It means re-organizing the above code so as to get hold of the property
- values before switching on the op-code. However, I wonder how many patterns
- combine ASCII \d etc with Unicode properties? (Note that if PCRE_UCP is set,
- these op-codes are never generated.) */
-
- case OP_DIGIT:
- return escape == ESC_D || escape == ESC_s || escape == ESC_W ||
- escape == ESC_h || escape == ESC_v || escape == ESC_R;
-
- case OP_NOT_DIGIT:
- return escape == ESC_d;
-
- case OP_WHITESPACE:
- return escape == ESC_S || escape == ESC_d || escape == ESC_w;
-
- case OP_NOT_WHITESPACE:
- return escape == ESC_s || escape == ESC_h || escape == ESC_v || escape == ESC_R;
-
- case OP_HSPACE:
- return escape == ESC_S || escape == ESC_H || escape == ESC_d ||
- escape == ESC_w || escape == ESC_v || escape == ESC_R;
-
- case OP_NOT_HSPACE:
- return escape == ESC_h;
-
- /* Can't have \S in here because VT matches \S (Perl anomaly) */
- case OP_ANYNL:
- case OP_VSPACE:
- return escape == ESC_V || escape == ESC_d || escape == ESC_w;
-
- case OP_NOT_VSPACE:
- return escape == ESC_v || escape == ESC_R;
-
- case OP_WORDCHAR:
- return escape == ESC_W || escape == ESC_s || escape == ESC_h ||
- escape == ESC_v || escape == ESC_R;
-
- case OP_NOT_WORDCHAR:
- return escape == ESC_w || escape == ESC_d;
-
- default:
- return FALSE;
- }
-
-/* Control does not reach here */
-}
-
-
-
-/*************************************************
* Add a character or range to a class *
*************************************************/
@@ -3672,22 +4328,22 @@ 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:
- optionsptr pointer to the option bits
- codeptr points to the pointer to the current code point
- ptrptr points to the current pattern pointer
- errorcodeptr points to error code variable
- firstcharptr place to put the first required character
+ optionsptr pointer to the option bits
+ codeptr points to the pointer to the current code point
+ ptrptr points to the current pattern pointer
+ errorcodeptr points to error code variable
+ firstcharptr place to put the first required character
firstcharflagsptr place to put the first character flags, or a negative number
- reqcharptr place to put the last required character
- reqcharflagsptr place to put the last required character flags, or a negative number
- 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
-
-Returns: TRUE on success
- FALSE, with *errorcodeptr set non-zero on error
+ reqcharptr place to put the last required character
+ reqcharflagsptr place to put the last required character flags, or a negative number
+ 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
+
+Returns: TRUE on success
+ FALSE, with *errorcodeptr set non-zero on error
*/
static BOOL
@@ -3910,58 +4566,67 @@ for (;; ptr++)
}
goto NORMAL_CHAR;
}
+ /* Control does not reach here. */
}
- /* Fill in length of a previous callout, except when the next thing is
- a quantifier. */
-
- is_quantifier =
- c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK ||
- (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1));
-
- if (!is_quantifier && previous_callout != NULL &&
- after_manual_callout-- <= 0)
- {
- if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
- complete_callout(previous_callout, ptr, cd);
- previous_callout = NULL;
- }
-
- /* In extended mode, skip white space and comments. */
+ /* In extended mode, skip white space and comments. We need a loop in order
+ to check for more white space and more comments after a comment. */
if ((options & PCRE_EXTENDED) != 0)
{
- if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue;
- if (c == CHAR_NUMBER_SIGN)
+ for (;;)
{
+ while (MAX_255(c) && (cd->ctypes[c] & ctype_space) != 0) c = *(++ptr);
+ if (c != CHAR_NUMBER_SIGN) break;
ptr++;
while (*ptr != CHAR_NULL)
{
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
+ if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */
+ { /* IS_NEWLINE sets cd->nllen. */
+ ptr += cd->nllen;
+ break;
+ }
ptr++;
#ifdef SUPPORT_UTF
if (utf) FORWARDCHAR(ptr);
#endif
}
- if (*ptr != CHAR_NULL) continue;
-
- /* Else fall through to handle end of string */
- c = 0;
+ c = *ptr; /* Either NULL or the char after a newline */
}
}
- /* No auto callout for quantifiers. */
+ /* See if the next thing is a quantifier. */
- if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier)
+ is_quantifier =
+ c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK ||
+ (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1));
+
+ /* Fill in length of a previous callout, except when the next thing is a
+ quantifier or when processing a property substitution string in UCP mode. */
+
+ if (!is_quantifier && previous_callout != NULL && nestptr == NULL &&
+ after_manual_callout-- <= 0)
+ {
+ if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
+ complete_callout(previous_callout, ptr, cd);
+ previous_callout = NULL;
+ }
+
+ /* Create auto callout, except for quantifiers, or while processing property
+ strings that are substituted for \w etc in UCP mode. */
+
+ if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier && nestptr == NULL)
{
previous_callout = code;
code = auto_callout(code, ptr, cd);
}
+ /* Process the next pattern item. */
+
switch(c)
{
/* ===================================================================*/
- case 0: /* The branch terminates at string end */
+ case CHAR_NULL: /* The branch terminates at string end */
case CHAR_VERTICAL_LINE: /* or | or ) */
case CHAR_RIGHT_PARENTHESIS:
*firstcharptr = firstchar;
@@ -4039,7 +4704,29 @@ for (;; ptr++)
}
goto NORMAL_CHAR;
+ /* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is
+ used for "start of word" and "end of word". As these are otherwise illegal
+ sequences, we don't break anything by recognizing them. They are replaced
+ by \b(?=\w) and \b(?<=\w) respectively. Sequences like [a[:<:]] are
+ erroneous and are handled by the normal code below. */
+
case CHAR_LEFT_SQUARE_BRACKET:
+ if (STRNCMP_UC_C8(ptr+1, STRING_WEIRD_STARTWORD, 6) == 0)
+ {
+ nestptr = ptr + 7;
+ ptr = sub_start_of_word - 1;
+ continue;
+ }
+
+ if (STRNCMP_UC_C8(ptr+1, STRING_WEIRD_ENDWORD, 6) == 0)
+ {
+ nestptr = ptr + 7;
+ ptr = sub_end_of_word - 1;
+ continue;
+ }
+
+ /* Handle a real character class. */
+
previous = code;
/* PCRE supports POSIX class stuff inside a class. Perl gives an error if
@@ -4204,24 +4891,58 @@ for (;; ptr++)
posix_class = 0;
/* When PCRE_UCP is set, some of the POSIX classes are converted to
- different escape sequences that use Unicode properties. */
+ different escape sequences that use Unicode properties \p or \P. Others
+ that are not available via \p or \P generate XCL_PROP/XCL_NOTPROP
+ directly. */
#ifdef SUPPORT_UCP
if ((options & PCRE_UCP) != 0)
{
+ unsigned int ptype = 0;
int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0);
+
+ /* The posix_substitutes table specifies which POSIX classes can be
+ converted to \p or \P items. */
+
if (posix_substitutes[pc] != NULL)
{
nestptr = tempptr + 1;
ptr = posix_substitutes[pc] - 1;
continue;
}
+
+ /* There are three other classes that generate special property calls
+ that are recognized only in an XCLASS. */
+
+ else switch(posix_class)
+ {
+ case PC_GRAPH:
+ ptype = PT_PXGRAPH;
+ /* Fall through */
+ case PC_PRINT:
+ if (ptype == 0) ptype = PT_PXPRINT;
+ /* Fall through */
+ case PC_PUNCT:
+ if (ptype == 0) ptype = PT_PXPUNCT;
+ *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP;
+ *class_uchardata++ = ptype;
+ *class_uchardata++ = 0;
+ ptr = tempptr + 1;
+ continue;
+
+ /* For all other POSIX classes, no special action is taken in UCP
+ mode. Fall through to the non_UCP case. */
+
+ default:
+ break;
+ }
}
#endif
- /* In the non-UCP case, we build the bit map for the POSIX class in a
- chunk of local store because we may be adding and subtracting from it,
- and we don't want to subtract bits that may be in the main map already.
- At the end we or the result into the bit map that is being built. */
+ /* In the non-UCP case, or when UCP makes no difference, we build the
+ bit map for the POSIX class in a chunk of local store because we may be
+ adding and subtracting from it, and we don't want to subtract bits that
+ may be in the main map already. At the end we or the result into the
+ bit map that is being built. */
posix_class *= 3;
@@ -4277,14 +4998,12 @@ for (;; ptr++)
if (c == CHAR_BACKSLASH)
{
- escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, TRUE);
-
+ escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options,
+ TRUE);
if (*errorcodeptr != 0) goto FAILED;
-
- if (escape == 0)
- c = ec;
+ if (escape == 0) c = ec;
else if (escape == ESC_b) c = CHAR_BS; /* \b is backspace in a class */
- else if (escape == ESC_N) /* \N is not supported in a class */
+ else if (escape == ESC_N) /* \N is not supported in a class */
{
*errorcodeptr = ERR71;
goto FAILED;
@@ -4340,21 +5059,20 @@ for (;; ptr++)
for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word];
continue;
- /* Perl 5.004 onwards omits VT from \s, but we must preserve it
- if it was previously set by something earlier in the character
- class. Luckily, the value of CHAR_VT is 0x0b in both ASCII and
- EBCDIC, so we lazily just adjust the appropriate bit. */
+ /* Perl 5.004 onwards omitted VT from \s, but restored it at Perl
+ 5.18. Before PCRE 8.34, we had to preserve the VT bit if it was
+ previously set by something earlier in the character class.
+ Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so
+ we could just adjust the appropriate bit. From PCRE 8.34 we no
+ longer treat \s and \S specially. */
case ESC_s:
- classbits[0] |= cbits[cbit_space];
- classbits[1] |= cbits[cbit_space+1] & ~0x08;
- for (c = 2; c < 32; c++) classbits[c] |= cbits[c+cbit_space];
+ for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_space];
continue;
case ESC_S:
should_flip_negation = TRUE;
for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space];
- classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */
continue;
/* The rest apply in both UCP and non-UCP cases. */
@@ -4476,26 +5194,43 @@ for (;; ptr++)
#endif
d = *ptr; /* Not UTF-8 mode */
- /* The second part of a range can be a single-character escape, but
- not any of the other escapes. Perl 5.6 treats a hyphen as a literal
- in such circumstances. */
+ /* The second part of a range can be a single-character escape
+ sequence, but not any of the other escapes. Perl treats a hyphen as a
+ literal in such circumstances. However, in Perl's warning mode, a
+ warning is given, so PCRE now faults it as it is almost certainly a
+ mistake on the user's part. */
- if (!inescq && d == CHAR_BACKSLASH)
+ if (!inescq)
{
- int descape;
- descape = check_escape(&ptr, &d, errorcodeptr, cd->bracount, options, TRUE);
- if (*errorcodeptr != 0) goto FAILED;
+ if (d == CHAR_BACKSLASH)
+ {
+ int descape;
+ descape = check_escape(&ptr, &d, errorcodeptr, cd->bracount, options, TRUE);
+ if (*errorcodeptr != 0) goto FAILED;
- /* \b is backspace; any other special means the '-' was literal. */
+ /* 0 means a character was put into d; \b is backspace; any other
+ special causes an error. */
- if (descape != 0)
- {
- if (descape == ESC_b) d = CHAR_BS; else
+ if (descape != 0)
{
- ptr = oldptr;
- goto CLASS_SINGLE_CHARACTER; /* A few lines below */
+ if (descape == ESC_b) d = CHAR_BS; else
+ {
+ *errorcodeptr = ERR83;
+ goto FAILED;
+ }
}
}
+
+ /* A hyphen followed by a POSIX class is treated in the same way. */
+
+ else if (d == CHAR_LEFT_SQUARE_BRACKET &&
+ (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
+ ptr[1] == CHAR_EQUALS_SIGN) &&
+ check_posix_syntax(ptr, &tempptr))
+ {
+ *errorcodeptr = ERR83;
+ goto FAILED;
+ }
}
/* Check that the two values are in the correct order. Optimize
@@ -4759,6 +5494,34 @@ for (;; ptr++)
tempcode = previous;
+ /* Before checking for a possessive quantifier, we must skip over
+ whitespace and comments in extended mode because Perl allows white space at
+ this point. */
+
+ if ((options & PCRE_EXTENDED) != 0)
+ {
+ const pcre_uchar *p = ptr + 1;
+ for (;;)
+ {
+ while (MAX_255(*p) && (cd->ctypes[*p] & ctype_space) != 0) p++;
+ if (*p != CHAR_NUMBER_SIGN) break;
+ p++;
+ while (*p != CHAR_NULL)
+ {
+ if (IS_NEWLINE(p)) /* For non-fixed-length newline cases, */
+ { /* IS_NEWLINE sets cd->nllen. */
+ p += cd->nllen;
+ break;
+ }
+ p++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(p);
+#endif
+ } /* Loop for comment characters */
+ } /* Loop for multiple comments */
+ ptr = p - 1; /* Character before the next significant one. */
+ }
+
/* If the next character is '+', we have a possessive quantifier. This
implies greediness, whatever the setting of the PCRE_UNGREEDY option.
If the next character is '?' this is a minimizing repeat, by default,
@@ -4853,19 +5616,6 @@ for (;; ptr++)
}
}
- /* If the repetition is unlimited, it pays to see if the next thing on
- the line is something that cannot possibly match this character. If so,
- automatically possessifying this item gains some performance in the case
- where the match fails. */
-
- if (!possessive_quantifier &&
- repeat_max < 0 &&
- check_auto_possessive(previous, utf, ptr + 1, options, cd))
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- }
-
goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */
}
@@ -4883,14 +5633,6 @@ for (;; ptr++)
op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */
c = *previous;
- if (!possessive_quantifier &&
- repeat_max < 0 &&
- check_auto_possessive(previous, utf, ptr + 1, options, cd))
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- }
-
OUTPUT_SINGLE_REPEAT:
if (*previous == OP_PROP || *previous == OP_NOTPROP)
{
@@ -4907,16 +5649,6 @@ for (;; ptr++)
if (repeat_max == 0) goto END_REPEAT;
- /*--------------------------------------------------------------------*/
- /* This code is obsolete from release 8.00; the restriction was finally
- removed: */
-
- /* All real repeats make it impossible to handle partial matching (maybe
- one day we will be able to remove this restriction). */
-
- /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
- /*--------------------------------------------------------------------*/
-
/* Combine the op_type with the repeat_type */
repeat_type += op_type;
@@ -5049,13 +5781,12 @@ for (;; ptr++)
/* If previous was a character class or a back reference, we put the repeat
stuff after it, but just skip the item if the repeat was {0,0}. */
- else if (*previous == OP_CLASS ||
- *previous == OP_NCLASS ||
+ else if (*previous == OP_CLASS || *previous == OP_NCLASS ||
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
*previous == OP_XCLASS ||
#endif
- *previous == OP_REF ||
- *previous == OP_REFI)
+ *previous == OP_REF || *previous == OP_REFI ||
+ *previous == OP_DNREF || *previous == OP_DNREFI)
{
if (repeat_max == 0)
{
@@ -5063,16 +5794,6 @@ for (;; ptr++)
goto END_REPEAT;
}
- /*--------------------------------------------------------------------*/
- /* This code is obsolete from release 8.00; the restriction was finally
- removed: */
-
- /* All real repeats make it impossible to handle partial matching (maybe
- one day we will be able to remove this restriction). */
-
- /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
- /*--------------------------------------------------------------------*/
-
if (repeat_min == 0 && repeat_max == -1)
*code++ = OP_CRSTAR + repeat_type;
else if (repeat_min == 1 && repeat_max == -1)
@@ -5093,8 +5814,9 @@ for (;; ptr++)
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. */
+ ASSERTBACK_NOT, ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND.
+ Originally, PCRE did not allow repetition of assertions, but now it does,
+ for Perl compatibility. */
else if (*previous >= OP_ASSERT && *previous <= OP_COND)
{
@@ -5112,7 +5834,7 @@ for (;; ptr++)
/* 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. */
+ maximum is not zero or one, set it to 1. */
if (*previous < OP_ONCE) /* Assertion */
{
@@ -5415,7 +6137,7 @@ for (;; ptr++)
pcre_uchar *scode = bracode;
do
{
- if (could_be_empty_branch(scode, ketcode, utf, cd))
+ if (could_be_empty_branch(scode, ketcode, utf, cd, NULL))
{
*bracode += OP_SBRA - OP_BRA;
break;
@@ -5485,43 +6207,105 @@ for (;; ptr++)
goto FAILED;
}
- /* If the character following a repeat is '+', or if certain optimization
- 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.
+ /* If the character following a repeat is '+', 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
- length of what remains before proceeding. */
+ 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. */
if (possessive_quantifier)
{
int len;
- if (*tempcode == OP_TYPEEXACT)
+ /* Possessifying an EXACT quantifier has no effect, so we can ignore it.
+ However, QUERY, STAR, or UPTO may follow (for quantifiers such as {5,6},
+ {5,}, or {5,10}). We skip over an EXACT item; if the length of what
+ remains is greater than zero, there's a further opcode that can be
+ handled. If not, do nothing, leaving the EXACT alone. */
+
+ switch(*tempcode)
+ {
+ case OP_TYPEEXACT:
tempcode += PRIV(OP_lengths)[*tempcode] +
((tempcode[1 + IMM2_SIZE] == OP_PROP
|| tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
+ break;
- else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT)
- {
+ /* CHAR opcodes are used for exacts whose count is 1. */
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
tempcode += PRIV(OP_lengths)[*tempcode];
#ifdef SUPPORT_UTF
if (utf && HAS_EXTRALEN(tempcode[-1]))
tempcode += GET_EXTRALEN(tempcode[-1]);
#endif
+ break;
+
+ /* For the class opcodes, the repeat operator appears at the end;
+ adjust tempcode to point to it. */
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ tempcode += 1 + 32/sizeof(pcre_uchar);
+ break;
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ tempcode += GET(tempcode, 1);
+ break;
+#endif
}
+ /* If tempcode is equal to code (which points to the end of the repeated
+ item), it means we have skipped an EXACT item but there is no following
+ QUERY, STAR, or UPTO; the value of len will be 0, and we do nothing. In
+ all other cases, tempcode will be pointing to the repeat opcode, and will
+ be less than code, so the value of len will be greater than 0. */
+
len = (int)(code - tempcode);
+ if (len > 0)
+ {
+ unsigned int repcode = *tempcode;
+
+ /* There is a table for possessifying opcodes, all of which are less
+ than OP_CALLOUT. A zero entry means there is no possessified version.
+ */
+
+ if (repcode < OP_CALLOUT && opcode_possessify[repcode] > 0)
+ *tempcode = opcode_possessify[repcode];
+
+ /* For opcode without a special possessified version, wrap the item in
+ ONCE brackets. Because we are moving code along, we must ensure that any
+ pending recursive references are updated. */
+
+ else
+ {
+ *code = OP_END;
+ 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;
+ *code++ = OP_KET;
+ PUTINC(code, 0, len);
+ PUT(tempcode, 1, len);
+ }
+ }
+
+#ifdef NEVER
if (len > 0) switch (*tempcode)
{
case OP_STAR: *tempcode = OP_POSSTAR; break;
@@ -5549,6 +6333,11 @@ for (;; ptr++)
case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break;
case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break;
+ case OP_CRSTAR: *tempcode = OP_CRPOSSTAR; break;
+ case OP_CRPLUS: *tempcode = OP_CRPOSPLUS; break;
+ case OP_CRQUERY: *tempcode = OP_CRPOSQUERY; break;
+ case OP_CRRANGE: *tempcode = OP_CRPOSRANGE; break;
+
/* Because we are moving code along, we must ensure that any
pending recursive references are updated. */
@@ -5564,6 +6353,7 @@ for (;; ptr++)
PUT(tempcode, 1, len);
break;
}
+#endif
}
/* In all case we no longer have a previous item. We also set the
@@ -5749,30 +6539,44 @@ for (;; ptr++)
/* ------------------------------------------------------------ */
case CHAR_LEFT_PARENTHESIS:
bravalue = OP_COND; /* Conditional group */
+ tempptr = ptr;
/* A condition can be an assertion, a number (referring to a numbered
- group), a name (referring to a named group), or 'R', referring to
- recursion. R<digits> and R&name are also permitted for recursion tests.
+ group's having been set), a name (referring to a named group), or 'R',
+ referring to recursion. R<digits> and R&name are also permitted for
+ recursion tests.
+
+ There are ways of testing a named group: (?(name)) is used by Python;
+ Perl 5.10 onwards uses (?(<name>) or (?('name')).
- There are several syntaxes for testing a named group: (?(name)) is used
- by Python; Perl 5.10 onwards uses (?(<name>) or (?('name')).
+ There is one unfortunate ambiguity, caused by history. 'R' can be the
+ recursive thing or the name 'R' (and similarly for 'R' followed by
+ digits). We look for a name first; if not found, we try the other case.
- There are two unfortunate ambiguities, caused by history. (a) 'R' can
- be the recursive thing or the name 'R' (and similarly for 'R' followed
- by digits), and (b) a number could be a name that consists of digits.
- In both cases, we look for a name first; if not found, we try the other
- cases. */
+ For compatibility with auto-callouts, we allow a callout to be
+ specified before a condition that is an assertion. First, check for the
+ syntax of a callout; if found, adjust the temporary pointer that is
+ used to check for an assertion condition. That's all that is needed! */
+
+ if (ptr[1] == CHAR_QUESTION_MARK && ptr[2] == CHAR_C)
+ {
+ for (i = 3;; i++) if (!IS_DIGIT(ptr[i])) break;
+ if (ptr[i] == CHAR_RIGHT_PARENTHESIS)
+ tempptr += i + 1;
+ }
/* For conditions that are assertions, check the syntax, and then exit
the switch. This will take control down to where bracketed groups,
including assertions, are processed. */
- if (ptr[1] == CHAR_QUESTION_MARK && (ptr[2] == CHAR_EQUALS_SIGN ||
- ptr[2] == CHAR_EXCLAMATION_MARK || ptr[2] == CHAR_LESS_THAN_SIGN))
+ if (tempptr[1] == CHAR_QUESTION_MARK &&
+ (tempptr[2] == CHAR_EQUALS_SIGN ||
+ tempptr[2] == CHAR_EXCLAMATION_MARK ||
+ tempptr[2] == CHAR_LESS_THAN_SIGN))
break;
- /* Most other conditions use OP_CREF (a couple change to OP_RREF
- below), and all need to skip 1+IMM2_SIZE bytes at the start of the group. */
+ /* Other conditions use OP_CREF/OP_DNCREF/OP_RREF/OP_DNRREF, and all
+ need to skip at least 1+IMM2_SIZE bytes at the start of the group. */
code[1+LINK_SIZE] = OP_CREF;
skipbytes = 1+IMM2_SIZE;
@@ -5780,7 +6584,8 @@ for (;; ptr++)
/* Check for a test for recursion in a named group. */
- if (ptr[1] == CHAR_R && ptr[2] == CHAR_AMPERSAND)
+ ptr++;
+ if (*ptr == CHAR_R && ptr[1] == CHAR_AMPERSAND)
{
terminator = -1;
ptr += 2;
@@ -5788,14 +6593,15 @@ for (;; ptr++)
}
/* Check for a test for a named group's having been set, using the Perl
- syntax (?(<name>) or (?('name') */
+ syntax (?(<name>) or (?('name'), and also allow for the original PCRE
+ syntax of (?(name) or for (?(+n), (?(-n), and just (?(n). */
- else if (ptr[1] == CHAR_LESS_THAN_SIGN)
+ else if (*ptr == CHAR_LESS_THAN_SIGN)
{
terminator = CHAR_GREATER_THAN_SIGN;
ptr++;
}
- else if (ptr[1] == CHAR_APOSTROPHE)
+ else if (*ptr == CHAR_APOSTROPHE)
{
terminator = CHAR_APOSTROPHE;
ptr++;
@@ -5803,35 +6609,55 @@ for (;; ptr++)
else
{
terminator = CHAR_NULL;
- if (ptr[1] == CHAR_MINUS || ptr[1] == CHAR_PLUS) refsign = *(++ptr);
+ if (*ptr == CHAR_MINUS || *ptr == CHAR_PLUS) refsign = *ptr++;
+ else if (IS_DIGIT(*ptr)) refsign = 0;
}
- /* We now expect to read a name; any thing else is an error */
+ /* Handle a number */
- if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0)
+ if (refsign >= 0)
{
- ptr += 1; /* To get the right offset */
- *errorcodeptr = ERR28;
- goto FAILED;
+ recno = 0;
+ while (IS_DIGIT(*ptr))
+ {
+ recno = recno * 10 + (int)(*ptr - CHAR_0);
+ ptr++;
+ }
}
- /* Read the name, but also get it as a number if it's all digits */
+ /* Otherwise we expect to read a name; anything else is an error. When
+ a name is one of a number of duplicates, a different opcode is used and
+ it needs more memory. Unfortunately we cannot tell whether a name is a
+ duplicate in the first pass, so we have to allow for more memory. */
- recno = 0;
- name = ++ptr;
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0)
+ else
{
- if (recno >= 0)
- recno = (IS_DIGIT(*ptr))? recno * 10 + (int)(*ptr - CHAR_0) : -1;
- ptr++;
+ if (IS_DIGIT(*ptr))
+ {
+ *errorcodeptr = ERR84;
+ goto FAILED;
+ }
+ if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_word) == 0)
+ {
+ *errorcodeptr = ERR28; /* Assertion expected */
+ goto FAILED;
+ }
+ name = ptr++;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0)
+ {
+ ptr++;
+ }
+ namelen = (int)(ptr - name);
+ if (lengthptr != NULL) *lengthptr += IMM2_SIZE;
}
- namelen = (int)(ptr - name);
+
+ /* Check the terminator */
if ((terminator > 0 && *ptr++ != (pcre_uchar)terminator) ||
*ptr++ != CHAR_RIGHT_PARENTHESIS)
{
- ptr--; /* Error offset */
- *errorcodeptr = ERR26;
+ ptr--; /* Error offset */
+ *errorcodeptr = ERR26; /* Malformed number or name */
goto FAILED;
}
@@ -5840,18 +6666,18 @@ for (;; ptr++)
if (lengthptr != NULL) break;
/* In the real compile we do the work of looking for the actual
- reference. If the string started with "+" or "-" we require the rest to
- be digits, in which case recno will be set. */
+ reference. If refsign is not negative, it means we have a number in
+ recno. */
- if (refsign > 0)
+ if (refsign >= 0)
{
if (recno <= 0)
{
- *errorcodeptr = ERR58;
+ *errorcodeptr = ERR35;
goto FAILED;
}
- recno = (refsign == CHAR_MINUS)?
- cd->bracount - recno + 1 : recno +cd->bracount;
+ if (refsign != 0) recno = (refsign == CHAR_MINUS)?
+ cd->bracount - recno + 1 : recno + cd->bracount;
if (recno <= 0 || recno > cd->final_bracount)
{
*errorcodeptr = ERR15;
@@ -5861,11 +6687,7 @@ for (;; ptr++)
break;
}
- /* Otherwise (did not start with "+" or "-"), start by looking for the
- name. If we find a name, add one to the opcode to change OP_CREF or
- OP_RREF into OP_NCREF or OP_NRREF. These behave exactly the same,
- except they record that the reference was originally to a name. The
- information is used to check duplicate names. */
+ /* Otherwise look for the name. */
slot = cd->name_table;
for (i = 0; i < cd->names_found; i++)
@@ -5874,29 +6696,40 @@ for (;; ptr++)
slot += cd->name_entry_size;
}
- /* Found a previous named subpattern */
+ /* Found the named subpattern. If the name is duplicated, add one to
+ the opcode to change CREF/RREF into DNCREF/DNRREF and insert
+ appropriate data values. Otherwise, just insert the unique subpattern
+ number. */
if (i < cd->names_found)
{
- recno = GET2(slot, 0);
- PUT2(code, 2+LINK_SIZE, recno);
- code[1+LINK_SIZE]++;
- }
-
- /* Search the pattern for a forward reference */
-
- else if ((i = find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf)) > 0)
- {
- PUT2(code, 2+LINK_SIZE, i);
- code[1+LINK_SIZE]++;
+ int offset = i++;
+ int count = 1;
+ recno = GET2(slot, 0); /* Number from first found */
+ for (; i < cd->names_found; i++)
+ {
+ slot += cd->name_entry_size;
+ if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) != 0) break;
+ count++;
+ }
+ if (count > 1)
+ {
+ PUT2(code, 2+LINK_SIZE, offset);
+ PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count);
+ skipbytes += IMM2_SIZE;
+ code[1+LINK_SIZE]++;
+ }
+ else /* Not a duplicated name */
+ {
+ PUT2(code, 2+LINK_SIZE, recno);
+ }
}
/* If terminator == CHAR_NULL it means that the name followed directly
after the opening parenthesis [e.g. (?(abc)...] and in this case there
are some further alternatives to try. For the cases where terminator !=
- 0 [things like (?(<name>... or (?('name')... or (?(R&name)... ] we have
- now checked all the possibilities, so give an error. */
+ CHAR_NULL [things like (?(<name>... or (?('name')... or (?(R&name)... ]
+ we have now checked all the possibilities, so give an error. */
else if (terminator != CHAR_NULL)
{
@@ -5933,19 +6766,11 @@ for (;; ptr++)
skipbytes = 1;
}
- /* Check for the "name" actually being a subpattern number. We are
- in the second pass here, so final_bracount is set. */
-
- else if (recno > 0 && recno <= cd->final_bracount)
- {
- PUT2(code, 2+LINK_SIZE, recno);
- }
-
- /* Either an unidentified subpattern, or a reference to (?(0) */
+ /* Reference to an unidentified subpattern. */
else
{
- *errorcodeptr = (recno == 0)? ERR35: ERR15;
+ *errorcodeptr = ERR15;
goto FAILED;
}
break;
@@ -5958,11 +6783,18 @@ for (;; ptr++)
ptr++;
break;
+ /* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird
+ thing to do, but Perl allows all assertions to be quantified, and when
+ they contain capturing parentheses there may be a potential use for
+ this feature. Not that that applies to a quantified (?!) but we allow
+ it for uniformity. */
/* ------------------------------------------------------------ */
case CHAR_EXCLAMATION_MARK: /* Negative lookahead */
ptr++;
- if (*ptr == CHAR_RIGHT_PARENTHESIS) /* Optimize (?!) */
+ if (*ptr == CHAR_RIGHT_PARENTHESIS && ptr[1] != CHAR_ASTERISK &&
+ ptr[1] != CHAR_PLUS && ptr[1] != CHAR_QUESTION_MARK &&
+ (ptr[1] != CHAR_LEFT_CURLY_BRACKET || !is_counted_repeat(ptr+2)))
{
*code++ = OP_FAIL;
previous = NULL;
@@ -6055,124 +6887,110 @@ for (;; ptr++)
/* ------------------------------------------------------------ */
DEFINE_NAME: /* Come here from (?< handling */
case CHAR_APOSTROPHE:
+ terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
+ CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
+ name = ++ptr;
+ if (IS_DIGIT(*ptr))
{
- terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
- CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
- name = ++ptr;
+ *errorcodeptr = ERR84; /* Group name must start with non-digit */
+ goto FAILED;
+ }
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
+ namelen = (int)(ptr - name);
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
- namelen = (int)(ptr - name);
+ /* In the pre-compile phase, do a syntax check, remember the longest
+ name, and then remember the group in a vector, expanding it if
+ necessary. Duplicates for the same number are skipped; other duplicates
+ are checked for validity. In the actual compile, there is nothing to
+ do. */
+
+ if (lengthptr != NULL)
+ {
+ named_group *ng;
+ pcre_uint32 number = cd->bracount + 1;
- /* In the pre-compile phase, just do a syntax check. */
+ if (*ptr != (pcre_uchar)terminator)
+ {
+ *errorcodeptr = ERR42;
+ goto FAILED;
+ }
- if (lengthptr != NULL)
+ if (cd->names_found >= MAX_NAME_COUNT)
{
- if (*ptr != (pcre_uchar)terminator)
- {
- *errorcodeptr = ERR42;
- goto FAILED;
- }
- if (cd->names_found >= MAX_NAME_COUNT)
+ *errorcodeptr = ERR49;
+ goto FAILED;
+ }
+
+ if (namelen + IMM2_SIZE + 1 > cd->name_entry_size)
+ {
+ cd->name_entry_size = namelen + IMM2_SIZE + 1;
+ if (namelen > MAX_NAME_SIZE)
{
- *errorcodeptr = ERR49;
+ *errorcodeptr = ERR48;
goto FAILED;
}
- if (namelen + IMM2_SIZE + 1 > cd->name_entry_size)
+ }
+
+ /* Scan the list to check for duplicates. For duplicate names, if the
+ number is the same, break the loop, which causes the name to be
+ discarded; otherwise, if DUPNAMES is not set, give an error.
+ If it is set, allow the name with a different number, but continue
+ scanning in case this is a duplicate with the same number. For
+ non-duplicate names, give an error if the number is duplicated. */
+
+ ng = cd->named_groups;
+ for (i = 0; i < cd->names_found; i++, ng++)
+ {
+ if (namelen == ng->length &&
+ STRNCMP_UC_UC(name, ng->name, namelen) == 0)
{
- cd->name_entry_size = namelen + IMM2_SIZE + 1;
- if (namelen > MAX_NAME_SIZE)
+ if (ng->number == number) break;
+ if ((options & PCRE_DUPNAMES) == 0)
{
- *errorcodeptr = ERR48;
+ *errorcodeptr = ERR43;
goto FAILED;
}
+ cd->dupnames = TRUE; /* Duplicate names exist */
+ }
+ else if (ng->number == number)
+ {
+ *errorcodeptr = ERR65;
+ goto FAILED;
}
}
- /* In the real compile, create the entry in the table, maintaining
- alphabetical order. Duplicate names for different numbers are
- permitted only if PCRE_DUPNAMES is set. Duplicate names for the same
- number are always OK. (An existing number can be re-used if (?|
- appears in the pattern.) In either event, a duplicate name results in
- a duplicate entry in the table, even if the number is the same. This
- is because the number of names, and hence the table size, is computed
- in the pre-compile, and it affects various numbers and pointers which
- would all have to be modified, and the compiled code moved down, if
- duplicates with the same number were omitted from the table. This
- doesn't seem worth the hassle. However, *different* names for the
- same number are not permitted. */
-
- else
+ if (i >= cd->names_found) /* Not a duplicate with same number */
{
- BOOL dupname = FALSE;
- slot = cd->name_table;
+ /* Increase the list size if necessary */
- for (i = 0; i < cd->names_found; i++)
+ if (cd->names_found >= cd->named_group_list_size)
{
- int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(namelen));
- if (crc == 0)
- {
- if (slot[IMM2_SIZE+namelen] == 0)
- {
- if (GET2(slot, 0) != cd->bracount + 1 &&
- (options & PCRE_DUPNAMES) == 0)
- {
- *errorcodeptr = ERR43;
- goto FAILED;
- }
- else dupname = TRUE;
- }
- else crc = -1; /* Current name is a substring */
- }
-
- /* Make space in the table and break the loop for an earlier
- name. For a duplicate or later name, carry on. We do this for
- duplicates so that in the simple case (when ?(| is not used) they
- are in order of their numbers. */
+ int newsize = cd->named_group_list_size * 2;
+ named_group *newspace = (PUBL(malloc))
+ (newsize * sizeof(named_group));
- if (crc < 0)
+ if (newspace == NULL)
{
- memmove(slot + cd->name_entry_size, slot,
- IN_UCHARS((cd->names_found - i) * cd->name_entry_size));
- break;
+ *errorcodeptr = ERR21;
+ goto FAILED;
}
- /* Continue the loop for a later or duplicate name */
-
- slot += cd->name_entry_size;
- }
-
- /* For non-duplicate names, check for a duplicate number before
- adding the new name. */
-
- if (!dupname)
- {
- pcre_uchar *cslot = cd->name_table;
- for (i = 0; i < cd->names_found; i++)
- {
- if (cslot != slot)
- {
- if (GET2(cslot, 0) == cd->bracount + 1)
- {
- *errorcodeptr = ERR65;
- goto FAILED;
- }
- }
- else i--;
- cslot += cd->name_entry_size;
- }
+ memcpy(newspace, cd->named_groups,
+ cd->named_group_list_size * sizeof(named_group));
+ if (cd->named_group_list_size > NAMED_GROUP_LIST_SIZE)
+ (PUBL(free))((void *)cd->named_groups);
+ cd->named_groups = newspace;
+ cd->named_group_list_size = newsize;
}
- PUT2(slot, 0, cd->bracount + 1);
- memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen));
- slot[IMM2_SIZE + namelen] = 0;
+ cd->named_groups[cd->names_found].name = name;
+ cd->named_groups[cd->names_found].length = namelen;
+ cd->named_groups[cd->names_found].number = number;
+ cd->names_found++;
}
}
- /* In both pre-compile and compile, count the number of names we've
- encountered. */
-
- cd->names_found++;
- ptr++; /* Move past > or ' */
+ ptr++; /* Move past > or ' in both passes. */
goto NUMBERED_GROUP;
@@ -6190,6 +7008,11 @@ for (;; ptr++)
NAMED_REF_OR_RECURSE:
name = ++ptr;
+ if (IS_DIGIT(*ptr))
+ {
+ *errorcodeptr = ERR84; /* Group name must start with non-digit */
+ goto FAILED;
+ }
while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
namelen = (int)(ptr - name);
@@ -6202,7 +7025,7 @@ for (;; ptr++)
if (lengthptr != NULL)
{
- const pcre_uchar *temp;
+ named_group *ng;
if (namelen == 0)
{
@@ -6220,27 +7043,29 @@ for (;; ptr++)
goto FAILED;
}
- /* The name table does not exist in the first pass, so we cannot
- do a simple search as in the code below. Instead, we have to scan the
- pattern to find the number. It is important that we scan it only as
- far as we have got because the syntax of named subpatterns has not
- been checked for the rest of the pattern, and find_parens() assumes
- correct syntax. In any case, it's a waste of resources to scan
- further. We stop the scan at the current point by temporarily
- adjusting the value of cd->endpattern. */
-
- temp = cd->end_pattern;
- cd->end_pattern = ptr;
- recno = find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf);
- cd->end_pattern = temp;
- if (recno < 0) recno = 0; /* Forward ref; set dummy number */
+ /* The name table does not exist in the first pass; instead we must
+ scan the list of names encountered so far in order to get the
+ number. If the name is not found, set the value to 0 for a forward
+ reference. */
+
+ ng = cd->named_groups;
+ for (i = 0; i < cd->names_found; i++, ng++)
+ {
+ if (namelen == ng->length &&
+ STRNCMP_UC_UC(name, ng->name, namelen) == 0)
+ break;
+ }
+ recno = (i < cd->names_found)? ng->number : 0;
+
+ /* Count named back references. */
+
+ if (!is_recurse) cd->namedrefcount++;
}
- /* In the real compile, seek the name in the table. We check the name
+ /* In the real compile, search the name table. We check the name
first, and then check that we have reached the end of the name in the
- table. That way, if the name that is longer than any in the table,
- the comparison will fail without reading beyond the table entry. */
+ table. That way, if the name is longer than any in the table, the
+ comparison will fail without reading beyond the table entry. */
else
{
@@ -6253,24 +7078,76 @@ for (;; ptr++)
slot += cd->name_entry_size;
}
- if (i < cd->names_found) /* Back reference */
+ if (i < cd->names_found)
{
recno = GET2(slot, 0);
}
- else if ((recno = /* Forward back reference */
- find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf)) <= 0)
+ else
{
*errorcodeptr = ERR15;
goto FAILED;
}
}
- /* In both phases, we can now go to the code than handles numerical
- recursion or backreferences. */
+ /* In both phases, for recursions, we can now go to the code than
+ handles numerical recursion. */
if (is_recurse) goto HANDLE_RECURSION;
- else goto HANDLE_REFERENCE;
+
+ /* In the second pass we must see if the name is duplicated. If so, we
+ generate a different opcode. */
+
+ if (lengthptr == NULL && cd->dupnames)
+ {
+ int count = 1;
+ unsigned int index = i;
+ pcre_uchar *cslot = slot + cd->name_entry_size;
+
+ for (i++; i < cd->names_found; i++)
+ {
+ if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break;
+ count++;
+ cslot += cd->name_entry_size;
+ }
+
+ if (count > 1)
+ {
+ if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
+ previous = code;
+ *code++ = ((options & PCRE_CASELESS) != 0)? OP_DNREFI : OP_DNREF;
+ PUT2INC(code, 0, index);
+ PUT2INC(code, 0, count);
+
+ /* Process each potentially referenced group. */
+
+ for (; slot < cslot; slot += cd->name_entry_size)
+ {
+ open_capitem *oc;
+ recno = GET2(slot, 0);
+ cd->backref_map |= (recno < 32)? (1 << recno) : 1;
+ if (recno > cd->top_backref) cd->top_backref = recno;
+
+ /* Check to see if this back reference is recursive, that it, it
+ is inside the group that it references. A flag is set so that the
+ group can be made atomic. */
+
+ for (oc = cd->open_caps; oc != NULL; oc = oc->next)
+ {
+ if (oc->number == recno)
+ {
+ oc->flag = TRUE;
+ break;
+ }
+ }
+ }
+
+ continue; /* End of back ref handling */
+ }
+ }
+
+ /* First pass, or a non-duplicated name. */
+
+ goto HANDLE_REFERENCE;
/* ------------------------------------------------------------ */
@@ -6369,8 +7246,7 @@ for (;; ptr++)
if (called == NULL)
{
- if (find_parens(cd, NULL, recno,
- (options & PCRE_EXTENDED) != 0, utf) < 0)
+ if (recno > cd->final_bracount)
{
*errorcodeptr = ERR15;
goto FAILED;
@@ -6529,10 +7405,19 @@ for (;; ptr++)
skipbytes = IMM2_SIZE;
}
- /* 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. */
+ /* Process nested bracketed regex. First check for parentheses nested too
+ deeply. */
+
+ if ((cd->parens_depth += 1) > PARENS_NEST_LIMIT)
+ {
+ *errorcodeptr = ERR82;
+ goto FAILED;
+ }
+
+ /* 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 = code; /* For handling repetition */
*code = bravalue;
@@ -6563,6 +7448,8 @@ for (;; ptr++)
))
goto FAILED;
+ cd->parens_depth -= 1;
+
/* If this was an atomic group and there are no capturing groups within it,
generate OP_ONCE_NC instead of OP_ONCE. */
@@ -6738,10 +7625,9 @@ for (;; ptr++)
case CHAR_BACKSLASH:
tempptr = ptr;
escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, FALSE);
-
if (*errorcodeptr != 0) goto FAILED;
- if (escape == 0)
+ if (escape == 0) /* The escape coded a single character */
c = ec;
else
{
@@ -6778,44 +7664,31 @@ for (;; ptr++)
if (escape == ESC_g)
{
const pcre_uchar *p;
+ pcre_uint32 cf;
+
save_hwm = cd->hwm; /* Normally this is set when '(' is read */
terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
/* These two statements stop the compiler for warning about possibly
unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In
- fact, because we actually check for a number below, the paths that
+ fact, because we do the check for a number below, the paths that
would actually be in error are never taken. */
skipbytes = 0;
reset_bracount = FALSE;
- /* Test for a name */
+ /* If it's not a signed or unsigned number, treat it as a name. */
- if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS)
+ cf = ptr[1];
+ if (cf != CHAR_PLUS && cf != CHAR_MINUS && !IS_DIGIT(cf))
{
- BOOL is_a_number = TRUE;
- for (p = ptr + 1; *p != CHAR_NULL && *p != (pcre_uchar)terminator; p++)
- {
- 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 != (pcre_uchar)terminator)
- {
- *errorcodeptr = ERR57;
- break;
- }
- if (is_a_number)
- {
- ptr++;
- goto HANDLE_NUMERICAL_RECURSION;
- }
is_recurse = TRUE;
goto NAMED_REF_OR_RECURSE;
}
- /* Test a signed number in angle brackets or quotes. */
+ /* Signed or unsigned number (cf = ptr[1]) is known to be plus or minus
+ or a digit. */
p = ptr + 2;
while (IS_DIGIT(*p)) p++;
@@ -6855,7 +7728,10 @@ for (;; ptr++)
open_capitem *oc;
recno = -escape;
- HANDLE_REFERENCE: /* Come here from named backref handling */
+ /* Come here from named backref handling when the reference is to a
+ single group (i.e. not to a duplicated name. */
+
+ HANDLE_REFERENCE:
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
previous = code;
*code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
@@ -6907,11 +7783,12 @@ for (;; ptr++)
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. Note that \b and \B do a one-character
- lookbehind. */
+ lookbehind, and \A also behaves as if it does. */
else
{
- if ((escape == ESC_b || escape == ESC_B) && cd->max_lookbehind == 0)
+ if ((escape == ESC_b || escape == ESC_B || escape == ESC_A) &&
+ cd->max_lookbehind == 0)
cd->max_lookbehind = 1;
#ifdef SUPPORT_UCP
if (escape >= ESC_DU && escape <= ESC_wu)
@@ -6951,8 +7828,8 @@ for (;; ptr++)
/* ===================================================================*/
/* Handle a literal character. It is guaranteed not to be whitespace or #
- when the extended flag is set. If we are in UTF-8 mode, it may be a
- multi-byte literal character. */
+ when the extended flag is set. If we are in a UTF mode, it may be a
+ multi-unit literal character. */
default:
NORMAL_CHAR:
@@ -6983,7 +7860,8 @@ for (;; ptr++)
*code++ = OP_PROP;
*code++ = PT_CLIST;
*code++ = c;
- if (firstcharflags == REQ_UNSET) firstcharflags = zerofirstcharflags = REQ_NONE;
+ if (firstcharflags == REQ_UNSET)
+ firstcharflags = zerofirstcharflags = REQ_NONE;
break;
}
}
@@ -7072,24 +7950,24 @@ 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
- 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)
- cond_depth depth of nesting for conditional subpatterns
- firstcharptr place to put the first required character
+ options option bits, including any changes for this subpattern
+ 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)
+ cond_depth depth of nesting for conditional subpatterns
+ firstcharptr place to put the first required character
firstcharflagsptr place to put the first character flags, or a negative number
- reqcharptr place to put the last required character
- reqcharflagsptr place to put the last required character flags, 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
- points to length accumulator during pre-compile phase
-
-Returns: TRUE on success
+ reqcharptr place to put the last required character
+ reqcharflagsptr place to put the last required character flags, 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
+ points to length accumulator during pre-compile phase
+
+Returns: TRUE on success
*/
static BOOL
@@ -7540,9 +8418,9 @@ do {
switch (*scode)
{
case OP_CREF:
- case OP_NCREF:
+ case OP_DNCREF:
case OP_RREF:
- case OP_NRREF:
+ case OP_DNRREF:
case OP_DEF:
return FALSE;
@@ -7626,13 +8504,14 @@ return TRUE;
discarded, because they can cause conflicts with actual literals that follow.
However, if we end up without a first char setting for an unanchored pattern,
it is worth scanning the regex to see if there is an initial asserted first
-char. If all branches start with the same asserted char, or with a bracket all
-of whose alternatives start with the same asserted char (recurse ad lib), then
-we return that char, otherwise -1.
+char. If all branches start with the same asserted char, or with a
+non-conditional bracket all of whose alternatives start with the same asserted
+char (recurse ad lib), then we return that char, with the flags set to zero or
+REQ_CASELESS; otherwise return zero with REQ_NONE in the flags.
Arguments:
code points to start of expression (the bracket)
- flags points to the first char flags, or to REQ_NONE
+ flags points to the first char flags, or to REQ_NONE
inassert TRUE if in an assertion
Returns: the fixed first char, or 0 with REQ_NONE in flags
@@ -7669,7 +8548,6 @@ do {
case OP_ASSERT:
case OP_ONCE:
case OP_ONCE_NC:
- case OP_COND:
d = find_firstassertedchar(scode, &dflags, op == OP_ASSERT);
if (dflags < 0)
return 0;
@@ -7714,6 +8592,61 @@ return c;
/*************************************************
+* Add an entry to the name/number table *
+*************************************************/
+
+/* This function is called between compiling passes to add an entry to the
+name/number table, maintaining alphabetical order. Checking for permitted
+and forbidden duplicates has already been done.
+
+Arguments:
+ cd the compile data block
+ name the name to add
+ length the length of the name
+ groupno the group number
+
+Returns: nothing
+*/
+
+static void
+add_name(compile_data *cd, const pcre_uchar *name, int length,
+ unsigned int groupno)
+{
+int i;
+pcre_uchar *slot = cd->name_table;
+
+for (i = 0; i < cd->names_found; i++)
+ {
+ int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(length));
+ if (crc == 0 && slot[IMM2_SIZE+length] != 0)
+ crc = -1; /* Current name is a substring */
+
+ /* Make space in the table and break the loop for an earlier name. For a
+ duplicate or later name, carry on. We do this for duplicates so that in the
+ simple case (when ?(| is not used) they are in order of their numbers. In all
+ cases they are in the order in which they appear in the pattern. */
+
+ if (crc < 0)
+ {
+ memmove(slot + cd->name_entry_size, slot,
+ IN_UCHARS((cd->names_found - i) * cd->name_entry_size));
+ break;
+ }
+
+ /* Continue the loop for a later or duplicate name */
+
+ slot += cd->name_entry_size;
+ }
+
+PUT2(slot, 0, groupno);
+memcpy(slot + IMM2_SIZE, name, IN_UCHARS(length));
+slot[IMM2_SIZE + length] = 0;
+cd->names_found++;
+}
+
+
+
+/*************************************************
* Compile a Regular Expression *
*************************************************/
@@ -7775,12 +8708,15 @@ pcre32_compile2(PCRE_SPTR32 pattern, int options, int *errorcodeptr,
{
REAL_PCRE *re;
int length = 1; /* For final END opcode */
-pcre_uint32 firstchar, reqchar;
pcre_int32 firstcharflags, reqcharflags;
+pcre_uint32 firstchar, reqchar;
+pcre_uint32 limit_match = PCRE_UINT32_MAX;
+pcre_uint32 limit_recursion = PCRE_UINT32_MAX;
int newline;
int errorcode = 0;
int skipatstart = 0;
BOOL utf;
+BOOL never_utf = FALSE;
size_t size;
pcre_uchar *code;
const pcre_uchar *codestart;
@@ -7797,6 +8733,11 @@ new memory is obtained from malloc(). */
pcre_uchar cworkspace[COMPILE_WORK_SIZE];
+/* This vector is used for remembering name groups during the pre-compile. In a
+similar way to cworkspace, it can be expanded using malloc() if necessary. */
+
+named_group named_groups[NAMED_GROUP_LIST_SIZE];
+
/* Set this early so that early errors get offset 0. */
ptr = (const pcre_uchar *)pattern;
@@ -7840,9 +8781,15 @@ if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
goto PCRE_EARLY_ERROR_RETURN;
}
+/* If PCRE_NEVER_UTF is set, remember it. */
+
+if ((options & PCRE_NEVER_UTF) != 0) never_utf = TRUE;
+
/* Check for global one-time settings at the start of the pattern, and remember
the offset for later. */
+cd->external_flags = 0; /* Initialize here for LIMIT_MATCH/RECURSION */
+
while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
ptr[skipatstart+1] == CHAR_ASTERISK)
{
@@ -7870,9 +8817,49 @@ PCRE_UTF8 == PCRE_UTF16 == PCRE_UTF32. */
{ skipatstart += 6; options |= PCRE_UTF8; continue; }
else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0)
{ skipatstart += 6; options |= PCRE_UCP; continue; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_AUTO_POSSESS_RIGHTPAR, 16) == 0)
+ { skipatstart += 18; options |= PCRE_NO_AUTO_POSSESS; continue; }
else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0)
{ skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LIMIT_MATCH_EQ, 12) == 0)
+ {
+ pcre_uint32 c = 0;
+ int p = skipatstart + 14;
+ while (isdigit(ptr[p]))
+ {
+ if (c > PCRE_UINT32_MAX / 10 - 1) break; /* Integer overflow */
+ c = c*10 + ptr[p++] - CHAR_0;
+ }
+ if (ptr[p++] != CHAR_RIGHT_PARENTHESIS) break;
+ if (c < limit_match)
+ {
+ limit_match = c;
+ cd->external_flags |= PCRE_MLSET;
+ }
+ skipatstart = p;
+ continue;
+ }
+
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LIMIT_RECURSION_EQ, 16) == 0)
+ {
+ pcre_uint32 c = 0;
+ int p = skipatstart + 18;
+ while (isdigit(ptr[p]))
+ {
+ if (c > PCRE_UINT32_MAX / 10 - 1) break; /* Integer overflow check */
+ c = c*10 + ptr[p++] - CHAR_0;
+ }
+ if (ptr[p++] != CHAR_RIGHT_PARENTHESIS) break;
+ if (c < limit_recursion)
+ {
+ limit_recursion = c;
+ cd->external_flags |= PCRE_RLSET;
+ }
+ skipatstart = p;
+ continue;
+ }
+
if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CR_RIGHTPAR, 3) == 0)
{ skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LF_RIGHTPAR, 3) == 0)
@@ -7898,6 +8885,11 @@ PCRE_UTF8 == PCRE_UTF16 == PCRE_UTF32. */
/* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
utf = (options & PCRE_UTF8) != 0;
+if (utf && never_utf)
+ {
+ errorcode = ERR78;
+ goto PCRE_EARLY_ERROR_RETURN2;
+ }
/* 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
@@ -8010,17 +9002,21 @@ cd->bracount = cd->final_bracount = 0;
cd->names_found = 0;
cd->name_entry_size = 0;
cd->name_table = NULL;
+cd->dupnames = FALSE;
+cd->namedrefcount = 0;
cd->start_code = cworkspace;
cd->hwm = cworkspace;
cd->start_workspace = cworkspace;
cd->workspace_size = COMPILE_WORK_SIZE;
+cd->named_groups = named_groups;
+cd->named_group_list_size = NAMED_GROUP_LIST_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->parens_depth = 0;
cd->assert_depth = 0;
cd->max_lookbehind = 0;
cd->external_options = options;
-cd->external_flags = 0;
cd->open_caps = NULL;
/* Now do the pre-compile. On error, errorcode will be set non-zero, so we
@@ -8032,6 +9028,7 @@ outside can help speed up starting point checks. */
ptr += skipatstart;
code = cworkspace;
*code = OP_BRA;
+
(void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE,
FALSE, 0, 0, &firstchar, &firstcharflags, &reqchar, &reqcharflags, NULL,
cd, &length);
@@ -8046,14 +9043,23 @@ if (length > MAX_PATTERN_SIZE)
goto PCRE_EARLY_ERROR_RETURN;
}
-/* Compute the size of data block needed and get it, either from malloc or
-externally provided function. Integer overflow should no longer be possible
-because nowadays we limit the maximum value of cd->names_found and
-cd->name_entry_size. */
+/* If there are groups with duplicate names and there are also references by
+name, we must allow for the possibility of named references to duplicated
+groups. These require an extra data item each. */
-size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar);
-re = (REAL_PCRE *)(PUBL(malloc))(size);
+if (cd->dupnames && cd->namedrefcount > 0)
+ length += cd->namedrefcount * IMM2_SIZE * sizeof(pcre_uchar);
+
+/* Compute the size of the data block for storing the compiled pattern. Integer
+overflow should no longer be possible because nowadays we limit the maximum
+value of cd->names_found and cd->name_entry_size. */
+
+size = sizeof(REAL_PCRE) +
+ (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar);
+
+/* Get the memory. */
+re = (REAL_PCRE *)(PUBL(malloc))(size);
if (re == NULL)
{
errorcode = ERR21;
@@ -8070,6 +9076,8 @@ re->magic_number = MAGIC_NUMBER;
re->size = (int)size;
re->options = cd->external_options;
re->flags = cd->external_flags;
+re->limit_match = limit_match;
+re->limit_recursion = limit_recursion;
re->first_char = 0;
re->req_char = 0;
re->name_table_offset = sizeof(REAL_PCRE) / sizeof(pcre_uchar);
@@ -8079,7 +9087,9 @@ re->ref_count = 0;
re->tables = (tables == PRIV(default_tables))? NULL : tables;
re->nullpad = NULL;
#ifdef COMPILE_PCRE32
-re->dummy1 = re->dummy2 = 0;
+re->dummy = 0;
+#else
+re->dummy1 = re->dummy2 = re->dummy3 = 0;
#endif
/* The starting points of the name/number translation table and of the code are
@@ -8090,10 +9100,10 @@ field; this time it's used for remembering forward references to subpatterns.
*/
cd->final_bracount = cd->bracount; /* Save for checking forward references */
+cd->parens_depth = 0;
cd->assert_depth = 0;
cd->bracount = 0;
cd->max_lookbehind = 0;
-cd->names_found = 0;
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;
@@ -8104,6 +9114,20 @@ cd->had_pruneorskip = FALSE;
cd->check_lookbehind = FALSE;
cd->open_caps = NULL;
+/* If any named groups were found, create the name/number table from the list
+created in the first pass. */
+
+if (cd->names_found > 0)
+ {
+ int i = cd->names_found;
+ named_group *ng = cd->named_groups;
+ cd->names_found = 0;
+ for (; i > 0; i--, ng++)
+ add_name(cd, ng->name, ng->length, ng->number);
+ if (cd->named_group_list_size > NAMED_GROUP_LIST_SIZE)
+ (PUBL(free))((void *)cd->named_groups);
+ }
+
/* Set up a starting, non-extracting bracket, then compile the expression. On
error, errorcode will be set non-zero, so we don't need to look at the result
of the function here. */
@@ -8167,16 +9191,24 @@ if (cd->hwm > cd->start_workspace)
}
}
-/* If the workspace had to be expanded, free the new memory. */
+/* If the workspace had to be expanded, free the new memory. Set the pointer to
+NULL to indicate that forward references have been filled in. */
if (cd->workspace_size > COMPILE_WORK_SIZE)
(PUBL(free))((void *)cd->start_workspace);
+cd->start_workspace = NULL;
/* Give an error if there's back reference to a non-existent capturing
subpattern. */
if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15;
+/* Unless disabled, check whether single character iterators can be
+auto-possessified. The function overwrites the appropriate opcode values. */
+
+if ((options & PCRE_NO_AUTO_POSSESS) == 0)
+ auto_possessify((pcre_uchar *)codestart, utf, cd);
+
/* If there were any lookbehind assertions that contained OP_RECURSE
(recursions or subroutine calls), a flag is set for them to be checked here,
because they may contain forward references. Actual recursions cannot be fixed
@@ -8374,6 +9406,20 @@ if (code - codestart > length)
}
#endif /* PCRE_DEBUG */
+/* Check for a pattern than can match an empty string, so that this information
+can be provided to applications. */
+
+do
+ {
+ if (could_be_empty_branch(codestart, code, utf, cd, NULL))
+ {
+ re->flags |= PCRE_MATCH_EMPTY;
+ break;
+ }
+ codestart += GET(codestart, 1);
+ }
+while (*codestart == OP_ALT);
+
#if defined COMPILE_PCRE8
return (pcre *)re;
#elif defined COMPILE_PCRE16
@@ -8384,3 +9430,4 @@ return (pcre32 *)re;
}
/* End of pcre_compile.c */
+
diff --git a/ext/pcre/pcrelib/pcre_config.c b/ext/pcre/pcrelib/pcre_config.c
index 3d5689f62c..1cbdd9c960 100644
--- a/ext/pcre/pcrelib/pcre_config.c
+++ b/ext/pcre/pcrelib/pcre_config.c
@@ -161,6 +161,10 @@ switch (what)
*((int *)where) = POSIX_MALLOC_THRESHOLD;
break;
+ case PCRE_CONFIG_PARENS_LIMIT:
+ *((unsigned long int *)where) = PARENS_NEST_LIMIT;
+ break;
+
case PCRE_CONFIG_MATCH_LIMIT:
*((unsigned long int *)where) = MATCH_LIMIT;
break;
diff --git a/ext/pcre/pcrelib/pcre_exec.c b/ext/pcre/pcrelib/pcre_exec.c
index 05d0e52d33..a3f0c1923f 100644
--- a/ext/pcre/pcrelib/pcre_exec.c
+++ b/ext/pcre/pcrelib/pcre_exec.c
@@ -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-2012 University of Cambridge
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -56,6 +56,20 @@ possible. There are also some static supporting functions. */
#undef min
#undef max
+/* The md->capture_last field uses the lower 16 bits for the last captured
+substring (which can never be greater than 65535) and a bit in the top half
+to mean "capture vector overflowed". This odd way of doing things was
+implemented when it was realized that preserving and restoring the overflow bit
+whenever the last capture number was saved/restored made for a neater
+interface, and doing it this way saved on (a) another variable, which would
+have increased the stack frame size (a big NO-NO in PCRE) and (b) another
+separate set of save/restore instructions. The following defines are used in
+implementing this. */
+
+#define CAPLMASK 0x0000ffff /* The bits used for last_capture */
+#define OVFLMASK 0xffff0000 /* The bits used for the overflow flag */
+#define OVFLBIT 0x00010000 /* The bit that is set for overflow */
+
/* 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. */
@@ -73,13 +87,17 @@ defined PCRE_ERROR_xxx codes, which are all negative. */
negative to avoid the external error codes. */
#define MATCH_ACCEPT (-999)
-#define MATCH_COMMIT (-998)
-#define MATCH_KETRPOS (-997)
-#define MATCH_ONCE (-996)
+#define MATCH_KETRPOS (-998)
+#define MATCH_ONCE (-997)
+/* The next 5 must be kept together and in sequence so that a test that checks
+for any one of them can use a range. */
+#define MATCH_COMMIT (-996)
#define MATCH_PRUNE (-995)
#define MATCH_SKIP (-994)
#define MATCH_SKIP_ARG (-993)
#define MATCH_THEN (-992)
+#define MATCH_BACKTRACK_MAX MATCH_THEN
+#define MATCH_BACKTRACK_MIN MATCH_COMMIT
/* 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,
@@ -89,8 +107,8 @@ because the offset vector is always a multiple of 3 long. */
/* Min and max values for the common repeats; for the maxima, 0 => infinity */
-static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
-static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
+static const char rep_min[] = { 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, };
+static const char rep_max[] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, };
#ifdef PCRE_DEBUG
/*************************************************
@@ -149,7 +167,7 @@ match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md,
{
PCRE_PUCHAR eptr_start = eptr;
register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
-#ifdef SUPPORT_UTF
+#if defined SUPPORT_UTF && defined SUPPORT_UCP
BOOL utf = md->utf;
#endif
@@ -177,8 +195,7 @@ ASCII characters. */
if (caseless)
{
-#ifdef SUPPORT_UTF
-#ifdef SUPPORT_UCP
+#if defined SUPPORT_UTF && defined SUPPORT_UCP
if (utf)
{
/* Match characters up to the end of the reference. NOTE: the number of
@@ -212,14 +229,13 @@ if (caseless)
}
else
#endif
-#endif
/* The same code works when not in UTF-8 mode and in UTF-8 mode when there
is no UCP support. */
{
while (length-- > 0)
{
- pcre_uchar cc, cp;
+ pcre_uint32 cc, cp;
if (eptr >= md->end_subject) return -2; /* Partial match */
cc = RAWUCHARTEST(eptr);
cp = RAWUCHARTEST(p);
@@ -416,10 +432,10 @@ typedef struct heapframe {
int Xlength;
int Xmax;
int Xmin;
- int Xnumber;
+ unsigned int Xnumber;
int Xoffset;
- int Xop;
- int Xsave_capture_last;
+ unsigned int Xop;
+ pcre_int32 Xsave_capture_last;
int Xsave_offset1, Xsave_offset2, Xsave_offset3;
int Xstacksave[REC_STACK_SAVE_MAX];
@@ -634,8 +650,8 @@ int max;
int min;
unsigned int number;
int offset;
-pcre_uchar op;
-int save_capture_last;
+unsigned int op;
+pcre_int32 save_capture_last;
int save_offset1, save_offset2, save_offset3;
int stacksave[REC_STACK_SAVE_MAX];
@@ -763,23 +779,16 @@ for (;;)
case OP_FAIL:
RRETURN(MATCH_NOMATCH);
- /* COMMIT overrides PRUNE, SKIP, and THEN */
-
case OP_COMMIT:
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);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
RRETURN(MATCH_COMMIT);
- /* PRUNE overrides THEN */
-
case OP_PRUNE:
RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
eptrb, RM51);
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
RRETURN(MATCH_PRUNE);
case OP_PRUNE_ARG:
@@ -789,38 +798,39 @@ for (;;)
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);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
RRETURN(MATCH_PRUNE);
- /* SKIP overrides PRUNE and THEN */
-
case OP_SKIP:
RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
eptrb, RM53);
- if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
- RRETURN(rrc);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
md->start_match_ptr = eptr; /* Pass back current position */
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. */
+ nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was
+ not a matching mark, we have to re-run the match, ignoring the SKIP_ARG
+ that failed and any that precede it (either they also failed, or were not
+ triggered). To do this, we maintain a count of executed SKIP_ARGs. If a
+ SKIP_ARG gets to top level, the match is re-run with md->ignore_skip_arg
+ set to the count of the one that failed. */
case OP_SKIP_ARG:
- if (md->ignore_skip_arg)
+ md->skip_arg_count++;
+ if (md->skip_arg_count <= 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);
+ if (rrc != MATCH_NOMATCH) 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 causes a rematch
- with the md->ignore_skip_arg flag set. */
+ with md->ignore_skip_arg set to the value of md->skip_arg_count. */
md->start_match_ptr = ecode + 2;
RRETURN(MATCH_SKIP_ARG);
@@ -1066,6 +1076,7 @@ for (;;)
/* In all other cases, we have to make another call to match(). */
save_mark = md->mark;
+ save_capture_last = md->capture_last;
RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
RM2);
@@ -1097,6 +1108,7 @@ for (;;)
ecode += GET(ecode, 1);
md->mark = save_mark;
if (*ecode != OP_ALT) break;
+ md->capture_last = save_capture_last;
}
RRETURN(MATCH_NOMATCH);
@@ -1159,6 +1171,7 @@ for (;;)
ecode = md->start_code + code_offset;
save_capture_last = md->capture_last;
matched_once = TRUE;
+ mstart = md->start_match_ptr; /* In case \K changed it */
continue;
}
@@ -1218,6 +1231,7 @@ for (;;)
POSSESSIVE_NON_CAPTURE:
matched_once = FALSE;
code_offset = (int)(ecode - md->start_code);
+ save_capture_last = md->capture_last;
for (;;)
{
@@ -1230,6 +1244,7 @@ for (;;)
eptr = md->end_match_ptr;
ecode = md->start_code + code_offset;
matched_once = TRUE;
+ mstart = md->start_match_ptr; /* In case \K reset it */
continue;
}
@@ -1247,6 +1262,7 @@ for (;;)
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode, 1);
if (*ecode != OP_ALT) break;
+ md->capture_last = save_capture_last;
}
if (matched_once || allow_zero)
@@ -1258,25 +1274,32 @@ for (;;)
/* 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. */
+ /* 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 of the item if there is only one branch, but that's exactly
+ what we want. */
case OP_COND:
case OP_SCOND:
- codelink = GET(ecode, 1);
+
+ /* The variable codelink will be added to ecode when the condition is
+ false, to get to the second branch. Setting it to the offset to the ALT
+ or KET, then incrementing ecode achieves this effect. We now have ecode
+ pointing to the condition or callout. */
+
+ codelink = GET(ecode, 1); /* Offset to the second branch */
+ ecode += 1 + LINK_SIZE; /* From this opcode */
/* 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 (*ecode == OP_CALLOUT)
{
if (PUBL(callout) != NULL)
{
PUBL(callout_block) cb;
cb.version = 2; /* Version 1 of the callout block */
- cb.callout_number = ecode[LINK_SIZE+2];
+ cb.callout_number = ecode[1];
cb.offset_vector = md->offset_vector;
#if defined COMPILE_PCRE8
cb.subject = (PCRE_SPTR)md->start_subject;
@@ -1288,215 +1311,130 @@ for (;;)
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);
- cb.pattern_position = GET(ecode, LINK_SIZE + 3);
- cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
+ cb.pattern_position = GET(ecode, 2);
+ cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
cb.capture_top = offset_top/2;
- cb.capture_last = md->capture_last;
+ cb.capture_last = md->capture_last & CAPLMASK;
+ /* Internal change requires this for API compatibility. */
+ if (cb.capture_last == 0) cb.capture_last = -1;
cb.callout_data = md->callout_data;
cb.mark = md->nomatch_mark;
if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
if (rrc < 0) RRETURN(rrc);
}
+
+ /* Advance ecode past the callout, so it now points to the condition. We
+ must adjust codelink so that the value of ecode+codelink is unchanged. */
+
ecode += PRIV(OP_lengths)[OP_CALLOUT];
+ codelink -= PRIV(OP_lengths)[OP_CALLOUT];
}
- condcode = ecode[LINK_SIZE+1];
+ /* Test the various possible conditions */
- /* Now see what the actual condition is */
-
- if (condcode == OP_RREF || condcode == OP_NRREF) /* Recursion test */
+ condition = FALSE;
+ switch(condcode = *ecode)
{
- if (md->recursive == NULL) /* Not recursing => FALSE */
- {
- condition = FALSE;
- ecode += GET(ecode, 1);
- }
- else
+ case OP_RREF: /* Numbered group recursion test */
+ if (md->recursive != NULL) /* Not recursing => FALSE */
{
- unsigned int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/
+ unsigned int recno = GET2(ecode, 1); /* Recursion group number*/
condition = (recno == RREF_ANY || recno == md->recursive->group_num);
+ }
+ break;
- /* 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)
+ case OP_DNRREF: /* Duplicate named group recursion test */
+ if (md->recursive != NULL)
+ {
+ int count = GET2(ecode, 1 + IMM2_SIZE);
+ pcre_uchar *slot = md->name_table + GET2(ecode, 1) * md->name_entry_size;
+ while (count-- > 0)
{
- pcre_uchar *slotA = md->name_table;
- for (i = 0; i < md->name_count; i++)
- {
- if (GET2(slotA, 0) == recno) break;
- slotA += md->name_entry_size;
- }
-
- /* 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. */
-
- if (i < md->name_count)
- {
- pcre_uchar *slotB = slotA;
- while (slotB > md->name_table)
- {
- slotB -= md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- condition = GET2(slotB, 0) == md->recursive->group_num;
- if (condition) break;
- }
- else break;
- }
-
- /* Scan up for duplicates */
-
- if (!condition)
- {
- slotB = slotA;
- for (i++; i < md->name_count; i++)
- {
- slotB += md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- condition = GET2(slotB, 0) == md->recursive->group_num;
- if (condition) break;
- }
- else break;
- }
- }
- }
+ unsigned int recno = GET2(slot, 0);
+ condition = recno == md->recursive->group_num;
+ if (condition) break;
+ slot += md->name_entry_size;
}
-
- /* Chose branch according to the condition */
-
- ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
}
- }
+ break;
- else if (condcode == OP_CREF || condcode == OP_NCREF) /* Group used test */
- {
- offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */
+ case OP_CREF: /* Numbered group used test */
+ offset = GET2(ecode, 1) << 1; /* Doubled ref number */
condition = offset < offset_top && md->offset_vector[offset] >= 0;
+ break;
- /* If the numbered capture is unset, but the reference was 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. This is tediously similar
- to the code above, but not close enough to try to amalgamate. */
-
- if (!condition && condcode == OP_NCREF)
+ case OP_DNCREF: /* Duplicate named group used test */
{
- unsigned int refno = offset >> 1;
- pcre_uchar *slotA = md->name_table;
-
- for (i = 0; i < md->name_count; i++)
+ int count = GET2(ecode, 1 + IMM2_SIZE);
+ pcre_uchar *slot = md->name_table + GET2(ecode, 1) * md->name_entry_size;
+ while (count-- > 0)
{
- if (GET2(slotA, 0) == refno) break;
- slotA += md->name_entry_size;
- }
-
- /* 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. */
-
- if (i < md->name_count)
- {
- pcre_uchar *slotB = slotA;
- while (slotB > md->name_table)
- {
- slotB -= md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- offset = GET2(slotB, 0) << 1;
- condition = offset < offset_top &&
- md->offset_vector[offset] >= 0;
- if (condition) break;
- }
- else break;
- }
-
- /* Scan up for duplicates */
-
- if (!condition)
- {
- slotB = slotA;
- for (i++; i < md->name_count; i++)
- {
- slotB += md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- offset = GET2(slotB, 0) << 1;
- condition = offset < offset_top &&
- md->offset_vector[offset] >= 0;
- if (condition) break;
- }
- else break;
- }
- }
+ offset = GET2(slot, 0) << 1;
+ condition = offset < offset_top && md->offset_vector[offset] >= 0;
+ if (condition) break;
+ slot += md->name_entry_size;
}
}
+ break;
- /* Chose branch according to the condition */
-
- ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
- }
-
- else if (condcode == OP_DEF) /* DEFINE - always false */
- {
- condition = FALSE;
- ecode += GET(ecode, 1);
- }
+ case OP_DEF: /* DEFINE - always false */
+ break;
- /* The condition is an assertion. Call match() to evaluate it - setting
- md->match_function_type to MATCH_CONDASSERT causes it to stop at the end of
- an assertion. */
+ /* The condition is an assertion. Call match() to evaluate it - setting
+ md->match_function_type to MATCH_CONDASSERT causes it to stop at the end
+ of an assertion. */
- else
- {
+ default:
md->match_function_type = MATCH_CONDASSERT;
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM3);
+ RMATCH(eptr, ecode, 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);
+
+ /* Advance ecode past the assertion to the start of the first branch,
+ but adjust it so that the general choosing code below works. */
+
+ ecode += GET(ecode, 1);
while (*ecode == OP_ALT) ecode += GET(ecode, 1);
+ ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode];
}
/* PCRE doesn't allow the effect of (*THEN) to escape beyond an
- assertion; it is therefore treated as NOMATCH. */
+ assertion; it is therefore treated as NOMATCH. Any other return is an
+ error. */
else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
{
RRETURN(rrc); /* Need braces because of following else */
}
- else
- {
- condition = FALSE;
- ecode += codelink;
- }
+ break;
}
- /* 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)
+ /* Choose branch according to the condition */
+
+ ecode += condition? PRIV(OP_lengths)[condcode] : codelink;
+
+ /* 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
+ 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[-(1+LINK_SIZE)] == OP_ALT)
{
if (op != OP_SCOND)
{
- ecode += 1 + LINK_SIZE;
goto TAIL_RECURSE;
}
md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM49);
RRETURN(rrc);
}
@@ -1504,7 +1442,6 @@ for (;;)
else
{
- ecode += 1 + LINK_SIZE;
}
break;
@@ -1513,7 +1450,7 @@ for (;;)
to close any currently open capturing brackets. */
case OP_CLOSE:
- number = GET2(ecode, 1);
+ number = GET2(ecode, 1); /* Must be less than 65536 */
offset = number << 1;
#ifdef PCRE_DEBUG
@@ -1521,8 +1458,8 @@ for (;;)
printf("\n");
#endif
- md->capture_last = number;
- if (offset >= md->offset_max) md->offset_overflow = TRUE; else
+ md->capture_last = (md->capture_last & OVFLMASK) | number;
+ if (offset >= md->offset_max) md->capture_last |= OVFLBIT; else
{
md->offset_vector[offset] =
md->offset_vector[md->offset_end - number];
@@ -1584,28 +1521,49 @@ for (;;)
}
else condassert = FALSE;
+ /* Loop for each branch */
+
do
{
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4);
+
+ /* A match means that the assertion is true; break out of the loop
+ that matches its alternatives. */
+
if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
{
mstart = md->start_match_ptr; /* In case \K reset it */
break;
}
+
+ /* If not matched, restore the previous mark setting. */
+
md->mark = save_mark;
- /* A COMMIT failure must fail the entire assertion, without trying any
- subsequent branches. */
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
- if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
- /* PCRE does not allow THEN to escape beyond an assertion; it
- is treated as NOMATCH. */
+ /* Anything other than NOMATCH causes the entire assertion to fail,
+ passing back the return code. This includes COMMIT, SKIP, PRUNE and an
+ uncaptured THEN, which means they take their normal effect. This
+ consistent approach does not always have exactly the same effect as in
+ Perl. */
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode, 1);
}
- while (*ecode == OP_ALT);
+ while (*ecode == OP_ALT); /* Continue for next alternative */
+
+ /* If we have tried all the alternative branches, the assertion has
+ failed. If not, we broke out after a match. */
if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
@@ -1613,17 +1571,16 @@ for (;;)
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. */
+ /* Continue from after a successful assertion, updating the offsets high
+ water mark, since extracts may have been taken during the assertion. */
do ecode += GET(ecode,1); while (*ecode == OP_ALT);
ecode += 1 + LINK_SIZE;
offset_top = md->end_offset_top;
continue;
- /* Negative assertion: all branches must fail to match. Encountering SKIP,
- PRUNE, or COMMIT means we must assume failure without checking subsequent
- branches. */
+ /* Negative assertion: all branches must fail to match for the assertion to
+ succeed. */
case OP_ASSERT_NOT:
case OP_ASSERTBACK_NOT:
@@ -1635,28 +1592,64 @@ for (;;)
}
else condassert = FALSE;
+ /* Loop for each alternative branch. */
+
do
{
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)
+ md->mark = save_mark; /* Always restore the mark setting */
+
+ switch(rrc)
{
- do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ case MATCH_MATCH: /* A successful match means */
+ case MATCH_ACCEPT: /* the assertion has failed. */
+ RRETURN(MATCH_NOMATCH);
+
+ case MATCH_NOMATCH: /* Carry on with next branch */
break;
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ case MATCH_THEN:
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ {
+ rrc = MATCH_NOMATCH;
+ break;
+ }
+ /* Otherwise fall through. */
+
+ /* COMMIT, SKIP, PRUNE, and an uncaptured THEN cause the whole
+ assertion to fail to match, without considering any more alternatives.
+ Failing to match means the assertion is true. This is a consistent
+ approach, but does not always have the same effect as in Perl. */
+
+ case MATCH_COMMIT:
+ case MATCH_SKIP:
+ case MATCH_SKIP_ARG:
+ case MATCH_PRUNE:
+ do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ goto NEG_ASSERT_TRUE; /* Break out of alternation loop */
+
+ /* Anything else is an error */
+
+ default:
+ RRETURN(rrc);
}
- /* PCRE does not allow THEN to escape beyond an assertion; it is treated
- as NOMATCH. */
+ /* Continue with next branch */
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
ecode += GET(ecode,1);
}
while (*ecode == OP_ALT);
- if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */
+ /* All branches in the assertion failed to match. */
- ecode += 1 + LINK_SIZE;
+ NEG_ASSERT_TRUE:
+ if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */
+ ecode += 1 + LINK_SIZE; /* Continue with current branch */
continue;
/* Move the subject pointer back. This occurs only at the start of
@@ -1716,7 +1709,9 @@ for (;;)
cb.pattern_position = GET(ecode, 2);
cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
cb.capture_top = offset_top/2;
- cb.capture_last = md->capture_last;
+ cb.capture_last = md->capture_last & CAPLMASK;
+ /* Internal change requires this for API compatibility. */
+ if (cb.capture_last == 0) cb.capture_last = -1;
cb.callout_data = md->callout_data;
cb.mark = md->nomatch_mark;
if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
@@ -1762,6 +1757,7 @@ for (;;)
/* Add to "recursing stack" */
new_recursive.group_num = recno;
+ new_recursive.saved_capture_last = md->capture_last;
new_recursive.subject_position = eptr;
new_recursive.prevrec = md->recursive;
md->recursive = &new_recursive;
@@ -1785,8 +1781,9 @@ for (;;)
new_recursive.saved_max * sizeof(int));
/* 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. */
+ restore the offset data and the last captured value. 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));
cbegroup = (*callpat >= OP_SBRA);
@@ -1797,6 +1794,7 @@ for (;;)
md, eptrb, RM6);
memcpy(md->offset_vector, new_recursive.offset_save,
new_recursive.saved_max * sizeof(int));
+ md->capture_last = new_recursive.saved_capture_last;
md->recursive = new_recursive.prevrec;
if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
{
@@ -1813,11 +1811,16 @@ for (;;)
goto RECURSION_MATCHED; /* Exit loop; end processing */
}
- /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it
- is treated as NOMATCH. */
+ /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a
+ recursion; they cause a NOMATCH for the entire recursion. These codes
+ are defined in a range that can be tested for. */
+
+ if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX)
+ RRETURN(MATCH_NOMATCH);
- else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
- rrc != MATCH_COMMIT)
+ /* Any return code other than NOMATCH is an error. */
+
+ if (rrc != MATCH_NOMATCH)
{
DPRINTF(("Recursion gave error %d\n", rrc));
if (new_recursive.offset_save != stacksave)
@@ -1947,8 +1950,8 @@ for (;;)
/* Deal with capturing */
- md->capture_last = number;
- if (offset >= md->offset_max) md->offset_overflow = TRUE; else
+ md->capture_last = (md->capture_last & OVFLMASK) | number;
+ if (offset >= md->offset_max) md->capture_last |= OVFLBIT; 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
@@ -2004,6 +2007,7 @@ for (;;)
if (*ecode == OP_KETRPOS)
{
+ md->start_match_ptr = mstart; /* In case \K reset it */
md->end_match_ptr = eptr;
md->end_offset_top = offset_top;
RRETURN(MATCH_KETRPOS);
@@ -2571,19 +2575,24 @@ for (;;)
RRETURN(MATCH_NOMATCH);
break;
- case PT_SPACE: /* Perl space */
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
- == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+ case PT_SPACE: /* Perl space */
case PT_PXSPACE: /* POSIX space */
- 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))
- RRETURN(MATCH_NOMATCH);
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) ==
+ (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH);
+ break;
+ }
break;
case PT_WORD:
@@ -2604,6 +2613,13 @@ for (;;)
}
break;
+ case PT_UCNC:
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
/* This should never occur */
default:
@@ -2650,15 +2666,7 @@ for (;;)
similar code to character type repeats - written out again for speed.
However, if the referenced string is the empty string, always treat
it as matched, any number of times (otherwise there could be infinite
- loops). */
-
- case OP_REF:
- 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:
+ loops). If the reference is unset, there are two possibilities:
(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
@@ -2668,8 +2676,39 @@ for (;;)
so that the back reference matches an empty string.
Otherwise, set the length to the length of what was matched by the
- referenced subpattern. */
+ referenced subpattern.
+
+ The OP_REF and OP_REFI opcodes are used for a reference to a numbered group
+ or to a non-duplicated named group. For a duplicated named group, OP_DNREF
+ and OP_DNREFI are used. In this case we must scan the list of groups to
+ which the name refers, and use the first one that is set. */
+
+ case OP_DNREF:
+ case OP_DNREFI:
+ caseless = op == OP_DNREFI;
+ {
+ int count = GET2(ecode, 1+IMM2_SIZE);
+ pcre_uchar *slot = md->name_table + GET2(ecode, 1) * md->name_entry_size;
+ ecode += 1 + 2*IMM2_SIZE;
+
+ while (count-- > 0)
+ {
+ offset = GET2(slot, 0) << 1;
+ if (offset < offset_top && md->offset_vector[offset] >= 0) break;
+ slot += md->name_entry_size;
+ }
+ if (count < 0)
+ length = (md->jscript_compat)? 0 : -1;
+ else
+ length = md->offset_vector[offset+1] - md->offset_vector[offset];
+ }
+ goto REF_REPEAT;
+ case OP_REF:
+ case OP_REFI:
+ caseless = op == OP_REFI;
+ offset = GET2(ecode, 1) << 1; /* Doubled ref number */
+ ecode += 1 + IMM2_SIZE;
if (offset >= offset_top || md->offset_vector[offset] < 0)
length = (md->jscript_compat)? 0 : -1;
else
@@ -2677,6 +2716,7 @@ for (;;)
/* Set up for repetition, or handle the non-repeated case */
+ REF_REPEAT:
switch (*ecode)
{
case OP_CRSTAR:
@@ -2825,8 +2865,12 @@ for (;;)
case OP_CRMINPLUS:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ case OP_CRPOSQUERY:
c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
+ if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0;
+ else possessive = TRUE;
min = rep_min[c]; /* Pick up values from tables; */
max = rep_max[c]; /* zero for max => infinity */
if (max == 0) max = INT_MAX;
@@ -2834,7 +2878,9 @@ for (;;)
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
minimize = (*ecode == OP_CRMINRANGE);
+ possessive = (*ecode == OP_CRPOSRANGE);
min = GET2(ecode, 1);
max = GET2(ecode, 1 + IMM2_SIZE);
if (max == 0) max = INT_MAX;
@@ -2976,6 +3022,9 @@ for (;;)
if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
eptr += len;
}
+
+ if (possessive) continue; /* No backtracking */
+
for (;;)
{
RMATCH(eptr, ecode, offset_top, md, eptrb, RM18);
@@ -3006,6 +3055,9 @@ for (;;)
if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
eptr++;
}
+
+ if (possessive) continue; /* No backtracking */
+
while (eptr >= pp)
{
RMATCH(eptr, ecode, offset_top, md, eptrb, RM19);
@@ -3021,9 +3073,10 @@ for (;;)
/* Control never gets here */
- /* Match an extended character class. This opcode is encountered only
- 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. */
+ /* Match an extended character class. In the 8-bit library, this opcode is
+ encountered only when UTF-8 mode mode is supported. In the 16-bit and
+ 32-bit libraries, codepoints greater than 255 may be encountered even when
+ UTF is not supported. */
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
case OP_XCLASS:
@@ -3039,8 +3092,12 @@ for (;;)
case OP_CRMINPLUS:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ case OP_CRPOSQUERY:
c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
+ if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0;
+ else possessive = TRUE;
min = rep_min[c]; /* Pick up values from tables; */
max = rep_max[c]; /* zero for max => infinity */
if (max == 0) max = INT_MAX;
@@ -3048,7 +3105,9 @@ for (;;)
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
minimize = (*ecode == OP_CRMINRANGE);
+ possessive = (*ecode == OP_CRPOSRANGE);
min = GET2(ecode, 1);
max = GET2(ecode, 1 + IMM2_SIZE);
if (max == 0) max = INT_MAX;
@@ -3120,6 +3179,9 @@ for (;;)
if (!PRIV(xclass)(c, data, utf)) break;
eptr += len;
}
+
+ if (possessive) continue; /* No backtracking */
+
for(;;)
{
RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
@@ -3190,7 +3252,7 @@ for (;;)
if (fc < 128)
{
- pcre_uchar cc = RAWUCHAR(eptr);
+ pcre_uint32 cc = RAWUCHAR(eptr);
if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH);
ecode++;
eptr++;
@@ -3295,7 +3357,22 @@ for (;;)
max = rep_max[c]; /* zero for max => infinity */
if (max == 0) max = INT_MAX;
- /* Common code for all repeated single-character matches. */
+ /* Common code for all repeated single-character matches. We first check
+ for the minimum number of characters. If the minimum equals the maximum, we
+ are done. Otherwise, if minimizing, check the rest of the pattern for a
+ match; if there isn't one, advance up to the maximum, one character at a
+ time.
+
+ If maximizing, advance up to the maximum number of matching characters,
+ until eptr is past the end of the maximum run. If possessive, we are
+ then 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. When we reach the first optional
+ character position, we can save stack by doing a tail recurse.
+
+ The various UTF/non-UTF and caseful/caseless cases are handled separately,
+ for speed. */
REPEATCHAR:
#ifdef SUPPORT_UTF
@@ -3379,13 +3456,12 @@ for (;;)
}
}
- if (possessive) continue;
-
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
#ifdef SUPPORT_UCP
eptr--;
BACKCHAR(eptr);
@@ -3439,8 +3515,7 @@ for (;;)
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc; /* Faster than pcre_uchar */
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -3455,8 +3530,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc; /* Faster than pcre_uchar */
RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max) RRETURN(MATCH_NOMATCH);
@@ -3476,8 +3550,7 @@ for (;;)
pp = eptr;
for (i = min; i < max; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc; /* Faster than pcre_uchar */
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -3487,18 +3560,16 @@ for (;;)
if (fc != cc && foc != cc) break;
eptr++;
}
-
- if (possessive) continue;
-
- while (eptr >= pp)
+ if (possessive) continue; /* No backtracking */
+ for (;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM25);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
- RRETURN(MATCH_NOMATCH);
+ /* Control never gets here */
}
- /* Control never gets here */
}
/* Caseful comparisons (includes all multi-byte characters) */
@@ -3546,15 +3617,15 @@ for (;;)
if (fc != RAWUCHARTEST(eptr)) break;
eptr++;
}
- if (possessive) continue;
-
- while (eptr >= pp)
+ if (possessive) continue; /* No backtracking */
+ for (;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM27);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
- RRETURN(MATCH_NOMATCH);
+ /* Control never gets here */
}
}
/* Control never gets here */
@@ -3726,7 +3797,7 @@ for (;;)
}
}
else
-#endif
+#endif /* SUPPORT_UTF */
/* Not UTF mode */
{
for (i = 1; i <= min; i++)
@@ -3764,7 +3835,7 @@ for (;;)
}
}
else
-#endif
+#endif /*SUPPORT_UTF */
/* Not UTF mode */
{
for (fi = min;; fi++)
@@ -3806,17 +3877,18 @@ for (;;)
if (fc == d || (unsigned int)foc == d) break;
eptr += len;
}
- if (possessive) continue;
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
+ eptr--;
BACKCHAR(eptr);
}
}
else
-#endif
+#endif /* SUPPORT_UTF */
/* Not UTF mode */
{
for (i = min; i < max; i++)
@@ -3829,18 +3901,17 @@ for (;;)
if (fc == *eptr || foc == *eptr) break;
eptr++;
}
- if (possessive) continue;
- while (eptr >= pp)
+ if (possessive) continue; /* No backtracking */
+ for (;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM31);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
}
-
- RRETURN(MATCH_NOMATCH);
+ /* Control never gets here */
}
- /* Control never gets here */
}
/* Caseful comparisons */
@@ -3941,12 +4012,13 @@ for (;;)
if (fc == d) break;
eptr += len;
}
- if (possessive) continue;
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM34);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
+ eptr--;
BACKCHAR(eptr);
}
}
@@ -3964,16 +4036,16 @@ for (;;)
if (fc == *eptr) break;
eptr++;
}
- if (possessive) continue;
- while (eptr >= pp)
+ if (possessive) continue; /* No backtracking */
+ for (;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM35);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
}
-
- RRETURN(MATCH_NOMATCH);
+ /* Control never gets here */
}
}
/* Control never gets here */
@@ -4155,7 +4227,12 @@ for (;;)
}
break;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
for (i = 1; i <= min; i++)
{
if (eptr >= md->end_subject)
@@ -4164,26 +4241,18 @@ for (;;)
RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_PXSPACE: /* POSIX space */
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
+ switch(c)
{
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ break;
}
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
}
break;
@@ -4225,6 +4294,22 @@ for (;;)
}
break;
+ case PT_UCNC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
/* This should not occur */
default:
@@ -4430,8 +4515,7 @@ for (;;)
case OP_DIGIT:
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -4448,8 +4532,7 @@ for (;;)
case OP_NOT_WHITESPACE:
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -4466,8 +4549,7 @@ for (;;)
case OP_WHITESPACE:
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -4484,8 +4566,7 @@ for (;;)
case OP_NOT_WORDCHAR:
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -4502,8 +4583,7 @@ for (;;)
case OP_WORDCHAR:
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -4892,25 +4972,11 @@ for (;;)
}
/* Control never gets here */
- case PT_SPACE: /* Perl space */
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+ case PT_SPACE: /* Perl space */
case PT_PXSPACE: /* POSIX space */
for (fi = min;; fi++)
{
@@ -4923,10 +4989,18 @@ for (;;)
RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ break;
+ }
}
/* Control never gets here */
@@ -4976,6 +5050,25 @@ for (;;)
}
/* Control never gets here */
+ case PT_UCNC:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
/* This should never occur */
default:
RRETURN(PCRE_ERROR_INTERNAL);
@@ -5391,7 +5484,12 @@ for (;;)
}
break;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
for (i = min; i < max; i++)
{
int len = 1;
@@ -5401,30 +5499,21 @@ for (;;)
break;
}
GETCHARLENTEST(c, eptr, len);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (prop_fail_result) goto ENDLOOP99; /* Break the loop */
break;
- eptr+= len;
- }
- break;
- case PT_PXSPACE: /* POSIX space */
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
+ default:
+ if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+ goto ENDLOOP99; /* Break the loop */
break;
}
- GETCHARLENTEST(c, eptr, len);
- 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;
eptr+= len;
}
+ ENDLOOP99:
break;
case PT_WORD:
@@ -5470,23 +5559,42 @@ for (;;)
GOT_MAX:
break;
+ case PT_UCNC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == prop_fail_result)
+ break;
+ eptr += len;
+ }
+ break;
+
default:
RRETURN(PCRE_ERROR_INTERNAL);
}
/* eptr is now past the end of the maximum run */
- if (possessive) continue;
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
+ eptr--;
if (utf) BACKCHAR(eptr);
}
}
- /* Match extended Unicode sequences. We will get here only if the
+ /* Match extended Unicode grapheme clusters. We will get here only if the
support is in the binary; otherwise a compile-time error occurs. */
else if (ctype == OP_EXTUNI)
@@ -5518,22 +5626,42 @@ for (;;)
/* eptr is now past the end of the maximum run */
- if (possessive) continue;
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ int lgb, rgb;
+ PCRE_PUCHAR fptr;
+
+ if (eptr == pp) goto TAIL_RECURSE; /* At start of char run */
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 */
+
+ /* Backtracking over an extended grapheme cluster involves inspecting
+ the previous two characters (if present) to see if a break is
+ permitted between them. */
+
+ eptr--;
+ if (!utf) c = *eptr; else
+ {
+ BACKCHAR(eptr);
+ GETCHAR(c, eptr);
+ }
+ rgb = UCD_GRAPHBREAK(c);
+
+ for (;;)
{
- if (!utf) c = *eptr; else
+ if (eptr == pp) goto TAIL_RECURSE; /* At start of char run */
+ fptr = eptr - 1;
+ if (!utf) c = *fptr; else
{
- BACKCHAR(eptr);
- GETCHAR(c, eptr);
+ BACKCHAR(fptr);
+ GETCHAR(c, fptr);
}
- if (UCD_CATEGORY(c) != ucp_M) break;
- eptr--;
+ lgb = UCD_GRAPHBREAK(c);
+ if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
+ eptr = fptr;
+ rgb = lgb;
}
}
}
@@ -5799,18 +5927,13 @@ for (;;)
RRETURN(PCRE_ERROR_INTERNAL);
}
- /* 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;
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM46);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
+ eptr--;
BACKCHAR(eptr);
if (ctype == OP_ANYNL && eptr > pp && RAWUCHAR(eptr) == CHAR_NL &&
RAWUCHAR(eptr - 1) == CHAR_CR) eptr--;
@@ -6048,15 +6171,10 @@ for (;;)
RRETURN(PCRE_ERROR_INTERNAL);
}
- /* 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)
+ if (possessive) continue; /* No backtracking */
+ for (;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
@@ -6065,11 +6183,8 @@ for (;;)
}
}
- /* Get here if we can't make it match with any permitted repetitions */
-
- RRETURN(MATCH_NOMATCH);
+ /* Control never gets here */
}
- /* Control never gets here */
/* There's been some horrible disaster. Arrival here can only mean there is
something seriously wrong in the code above or the OP_xxx definitions. */
@@ -6103,10 +6218,10 @@ switch (frame->Xwhere)
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)
+ LBL(20) LBL(21)
#endif
#ifdef SUPPORT_UTF
- LBL(16) LBL(18) LBL(20)
+ LBL(16) LBL(18)
LBL(22) LBL(23) LBL(28) LBL(30)
LBL(32) LBL(34) LBL(42) LBL(46)
#ifdef SUPPORT_UCP
@@ -6264,6 +6379,7 @@ 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 match_partial = NULL;
PCRE_PUCHAR req_char_ptr = start_match - 1;
const pcre_study_data *study;
@@ -6393,6 +6509,8 @@ md->callout_data = NULL;
tables = re->tables;
+/* The two limit values override the defaults, whatever their value. */
+
if (extra_data != NULL)
{
register unsigned int flags = extra_data->flags;
@@ -6407,6 +6525,15 @@ if (extra_data != NULL)
if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
}
+/* Limits in the regex override only if they are smaller. */
+
+if ((re->flags & PCRE_MLSET) != 0 && re->limit_match < md->match_limit)
+ md->match_limit = re->limit_match;
+
+if ((re->flags & PCRE_RLSET) != 0 &&
+ re->limit_recursion < md->match_limit_recursion)
+ md->match_limit_recursion = re->limit_recursion;
+
/* If the exec call supplied NULL for tables, use the inbuilt ones. This
is a feature that makes it possible to save compiled regex and re-use them
in other programs later. */
@@ -6432,7 +6559,7 @@ end_subject = md->end_subject;
md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
md->use_ucp = (re->options & PCRE_UCP) != 0;
md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
-md->ignore_skip_arg = FALSE;
+md->ignore_skip_arg = 0;
/* Some options are unpacked into BOOL variables in the hope that testing
them will be faster than individual option bits. */
@@ -6542,11 +6669,9 @@ if (re->top_backref > 0 && re->top_backref >= ocount/3)
DPRINTF(("Got memory to hold back references\n"));
}
else md->offset_vector = offsets;
-
md->offset_end = ocount;
md->offset_max = (2*ocount)/3;
-md->offset_overflow = FALSE;
-md->capture_last = -1;
+md->capture_last = 0;
/* 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
@@ -6816,8 +6941,13 @@ for(;;)
md->match_call_count = 0;
md->match_function_type = 0;
md->end_offset_top = 0;
+ md->skip_arg_count = 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;
+ if (md->hitend && start_partial == NULL)
+ {
+ start_partial = md->start_used_ptr;
+ match_partial = start_match;
+ }
switch(rc)
{
@@ -6830,14 +6960,14 @@ for(;;)
case MATCH_SKIP_ARG:
new_start_match = start_match;
- md->ignore_skip_arg = TRUE;
+ md->ignore_skip_arg = md->skip_arg_count;
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. */
+ /* SKIP passes back the next starting point explicitly, but if it is no
+ greater than the match we have just done, treat it as NOMATCH. */
case MATCH_SKIP:
- if (md->start_match_ptr != start_match)
+ if (md->start_match_ptr > start_match)
{
new_start_match = md->start_match_ptr;
break;
@@ -6845,12 +6975,12 @@ for(;;)
/* Fall through */
/* NOMATCH and PRUNE advance by one character. THEN at this level acts
- exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */
+ exactly like PRUNE. Unset ignore SKIP-with-argument. */
case MATCH_NOMATCH:
case MATCH_PRUNE:
case MATCH_THEN:
- md->ignore_skip_arg = FALSE;
+ md->ignore_skip_arg = 0;
new_start_match = start_match + 1;
#ifdef SUPPORT_UTF
if (utf)
@@ -6943,7 +7073,7 @@ if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
(arg_offset_max - 2) * sizeof(int));
DPRINTF(("Copied offsets from temporary memory\n"));
}
- if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;
+ if (md->end_offset_top > arg_offset_max) md->capture_last |= OVFLBIT;
DPRINTF(("Freeing temporary memory\n"));
(PUBL(free))(md->offset_vector);
}
@@ -6951,7 +7081,8 @@ if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
/* 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 && md->end_offset_top >= arg_offset_max)?
+ rc = ((md->capture_last & OVFLBIT) != 0 &&
+ 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
@@ -7016,7 +7147,7 @@ if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
/* Handle partial matches - disable any mark data */
-if (start_partial != NULL)
+if (match_partial != NULL)
{
DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
md->mark = NULL;
@@ -7024,6 +7155,8 @@ if (start_partial != NULL)
{
offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
+ if (offsetcount > 2)
+ offsets[2] = (int)(match_partial - (PCRE_PUCHAR)subject);
}
rc = PCRE_ERROR_PARTIAL;
}
diff --git a/ext/pcre/pcrelib/pcre_fullinfo.c b/ext/pcre/pcrelib/pcre_fullinfo.c
index 02c9df4a82..a6c2ece6ca 100644
--- a/ext/pcre/pcrelib/pcre_fullinfo.c
+++ b/ext/pcre/pcrelib/pcre_fullinfo.c
@@ -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-2012 University of Cambridge
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -222,6 +222,20 @@ switch (what)
*((int *)where) = re->max_lookbehind;
break;
+ case PCRE_INFO_MATCHLIMIT:
+ if ((re->flags & PCRE_MLSET) == 0) return PCRE_ERROR_UNSET;
+ *((pcre_uint32 *)where) = re->limit_match;
+ break;
+
+ case PCRE_INFO_RECURSIONLIMIT:
+ if ((re->flags & PCRE_RLSET) == 0) return PCRE_ERROR_UNSET;
+ *((pcre_uint32 *)where) = re->limit_recursion;
+ break;
+
+ case PCRE_INFO_MATCH_EMPTY:
+ *((int *)where) = (re->flags & PCRE_MATCH_EMPTY) != 0;
+ break;
+
default: return PCRE_ERROR_BADOPTION;
}
diff --git a/ext/pcre/pcrelib/pcre_internal.h b/ext/pcre/pcrelib/pcre_internal.h
index 43f5364556..0b9798c554 100644
--- a/ext/pcre/pcrelib/pcre_internal.h
+++ b/ext/pcre/pcrelib/pcre_internal.h
@@ -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-2012 University of Cambridge
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -194,23 +194,31 @@ preprocessor time in standard C environments. */
typedef unsigned char pcre_uint8;
#if USHRT_MAX == 65535
- typedef unsigned short pcre_uint16;
- typedef short pcre_int16;
+typedef unsigned short pcre_uint16;
+typedef short pcre_int16;
+#define PCRE_UINT16_MAX USHRT_MAX
+#define PCRE_INT16_MAX SHRT_MAX
#elif UINT_MAX == 65535
- typedef unsigned int pcre_uint16;
- typedef int pcre_int16;
+typedef unsigned int pcre_uint16;
+typedef int pcre_int16;
+#define PCRE_UINT16_MAX UINT_MAX
+#define PCRE_INT16_MAX INT_MAX
#else
-# error Cannot determine a type for 16-bit unsigned integers
+#error Cannot determine a type for 16-bit integers
#endif
-#if UINT_MAX == 4294967295
- typedef unsigned int pcre_uint32;
- typedef int pcre_int32;
-#elif ULONG_MAX == 4294967295
- typedef unsigned long int pcre_uint32;
- typedef long int pcre_int32;
+#if UINT_MAX == 4294967295U
+typedef unsigned int pcre_uint32;
+typedef int pcre_int32;
+#define PCRE_UINT32_MAX UINT_MAX
+#define PCRE_INT32_MAX INT_MAX
+#elif ULONG_MAX == 4294967295UL
+typedef unsigned long int pcre_uint32;
+typedef long int pcre_int32;
+#define PCRE_UINT32_MAX ULONG_MAX
+#define PCRE_INT32_MAX LONG_MAX
#else
-# error Cannot determine a type for 32-bit unsigned integers
+#error Cannot determine a type for 32-bit integers
#endif
/* When checking for integer overflow in pcre_compile(), we need to handle
@@ -221,11 +229,9 @@ stdint.h is available, include it; it may define INT64_MAX. Systems that do not
have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set
by "configure". */
-#ifdef PHP_WIN32
-#include "win32/php_stdint.h"
-#elif HAVE_STDINT_H
+#if defined HAVE_STDINT_H
#include <stdint.h>
-#elif HAVE_INTTYPES_H
+#elif defined HAVE_INTTYPES_H
#include <inttypes.h>
#endif
@@ -1123,23 +1129,27 @@ other. NOTE: The values also appear in pcre_jit_compile.c. */
/* 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
+live at the top end of the options word, but that got almost full, so they were
+moved to a 16-bit flags word - which got almost full, so now they are in a
+32-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_MODE8 0x0001 /* compiled in 8 bit mode */
-#define PCRE_MODE16 0x0002 /* compiled in 16 bit mode */
-#define PCRE_MODE32 0x0004 /* compiled in 32 bit mode */
-#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) */
+#define PCRE_MODE8 0x00000001 /* compiled in 8 bit mode */
+#define PCRE_MODE16 0x00000002 /* compiled in 16 bit mode */
+#define PCRE_MODE32 0x00000004 /* compiled in 32 bit mode */
+#define PCRE_FIRSTSET 0x00000010 /* first_char is set */
+#define PCRE_FCH_CASELESS 0x00000020 /* caseless first char */
+#define PCRE_REQCHSET 0x00000040 /* req_byte is set */
+#define PCRE_RCH_CASELESS 0x00000080 /* caseless requested char */
+#define PCRE_STARTLINE 0x00000100 /* start after \n for multiline */
+#define PCRE_NOPARTIAL 0x00000200 /* can't use partial with this regex */
+#define PCRE_JCHANGED 0x00000400 /* j option used in regex */
+#define PCRE_HASCRORLF 0x00000800 /* explicit \r or \n in pattern */
+#define PCRE_HASTHEN 0x00001000 /* pattern contains (*THEN) */
+#define PCRE_MLSET 0x00002000 /* match limit set by regex */
+#define PCRE_RLSET 0x00004000 /* recursion limit set by regex */
+#define PCRE_MATCH_EMPTY 0x00008000 /* pattern can match empty string */
#if defined COMPILE_PCRE8
#define PCRE_MODE PCRE_MODE8
@@ -1164,9 +1174,10 @@ time, run time, or study time, respectively. */
#define PUBLIC_COMPILE_OPTIONS \
(PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
- PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \
+ PCRE_NO_AUTO_CAPTURE|PCRE_NO_AUTO_POSSESS| \
+ PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \
PCRE_DUPNAMES|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
- PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE)
+ PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE|PCRE_NEVER_UTF)
#define PUBLIC_EXEC_OPTIONS \
(PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
@@ -1522,20 +1533,25 @@ a positive value. */
#define STRING_xdigit "xdigit"
#define STRING_DEFINE "DEFINE"
-
-#define STRING_CR_RIGHTPAR "CR)"
-#define STRING_LF_RIGHTPAR "LF)"
-#define STRING_CRLF_RIGHTPAR "CRLF)"
-#define STRING_ANY_RIGHTPAR "ANY)"
-#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)"
-#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)"
-#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)"
-#define STRING_UTF8_RIGHTPAR "UTF8)"
-#define STRING_UTF16_RIGHTPAR "UTF16)"
-#define STRING_UTF32_RIGHTPAR "UTF32)"
-#define STRING_UTF_RIGHTPAR "UTF)"
-#define STRING_UCP_RIGHTPAR "UCP)"
-#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
+#define STRING_WEIRD_STARTWORD "[:<:]]"
+#define STRING_WEIRD_ENDWORD "[:>:]]"
+
+#define STRING_CR_RIGHTPAR "CR)"
+#define STRING_LF_RIGHTPAR "LF)"
+#define STRING_CRLF_RIGHTPAR "CRLF)"
+#define STRING_ANY_RIGHTPAR "ANY)"
+#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)"
+#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)"
+#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)"
+#define STRING_UTF8_RIGHTPAR "UTF8)"
+#define STRING_UTF16_RIGHTPAR "UTF16)"
+#define STRING_UTF32_RIGHTPAR "UTF32)"
+#define STRING_UTF_RIGHTPAR "UTF)"
+#define STRING_UCP_RIGHTPAR "UCP)"
+#define STRING_NO_AUTO_POSSESS_RIGHTPAR "NO_AUTO_POSSESS)"
+#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
+#define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH="
+#define STRING_LIMIT_RECURSION_EQ "LIMIT_RECURSION="
#else /* SUPPORT_UTF */
@@ -1783,20 +1799,25 @@ only. */
#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t
#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E
-
-#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS
-#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS
-#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
-#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
-#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS
-#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS
-#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
+#define STRING_WEIRD_STARTWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET
+#define STRING_WEIRD_ENDWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET
+
+#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS
+#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS
+#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
+#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
+#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS
+#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS
+#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS
+#define STRING_NO_AUTO_POSSESS_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_A STR_U STR_T STR_O STR_UNDERSCORE STR_P STR_O STR_S STR_S STR_E STR_S STR_S 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
+#define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN
+#define STRING_LIMIT_RECURSION_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN
#endif /* SUPPORT_UTF */
@@ -1837,6 +1858,18 @@ only. */
#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */
#define PT_WORD 8 /* Word - L plus N plus underscore */
#define PT_CLIST 9 /* Pseudo-property: match character list */
+#define PT_UCNC 10 /* Universal Character nameable character */
+#define PT_TABSIZE 11 /* Size of square table for autopossessify tests */
+
+/* The following special properties are used only in XCLASS items, when POSIX
+classes are specified and PCRE_UCP is set - in other words, for Unicode
+handling of these classes. They are not available via the \p or \P escapes like
+those in the above list, and so they do not take part in the autopossessifying
+table. */
+
+#define PT_PXGRAPH 11 /* [:graph:] - characters that mark the paper */
+#define PT_PXPRINT 12 /* [:print:] - [:graph:] plus non-control spaces */
+#define PT_PXPUNCT 13 /* [:punct:] - punctuation characters */
/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
contain characters with values greater than 255. */
@@ -1851,9 +1884,9 @@ contain characters with values greater than 255. */
#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */
/* These are escaped items that aren't just an encoding of a particular data
-value such as \n. They must have non-zero values, as check_escape() returns
-0 for a data character. 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
+value such as \n. They must have non-zero values, as check_escape() returns 0
+for a data character. 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, and for \C in non-utf mode. In
non-DOTALL mode, "." behaves like \N.
@@ -1876,12 +1909,31 @@ enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
ESC_E, ESC_Q, ESC_g, ESC_k,
ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu };
-/* Opcode table: Starting from 1 (i.e. after OP_END), the values up to
-OP_EOD must correspond in order to the list of escapes immediately above.
-*** NOTE NOTE NOTE *** Whenever this list is updated, the two macro definitions
-that follow must also be updated to match. There are also tables called
-"coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */
+/********************** Opcode definitions ******************/
+
+/****** NOTE NOTE NOTE ******
+
+Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in
+order to the list of escapes immediately above. Furthermore, values up to
+OP_DOLLM must not be changed without adjusting the table called autoposstab in
+pcre_compile.c
+
+Whenever this list is updated, the two macro definitions that follow must be
+updated to match. The possessification table called "opcode_possessify" in
+pcre_compile.c must also be updated, and also the tables called "coptable"
+and "poptable" in pcre_dfa_exec.c.
+
+****** NOTE NOTE NOTE ******/
+
+
+/* The values between FIRST_AUTOTAB_OP and LAST_AUTOTAB_RIGHT_OP, inclusive,
+are used in a table for deciding whether a repeated character type can be
+auto-possessified. */
+
+#define FIRST_AUTOTAB_OP OP_NOT_DIGIT
+#define LAST_AUTOTAB_LEFT_OP OP_EXTUNI
+#define LAST_AUTOTAB_RIGHT_OP OP_DOLLM
enum {
OP_END, /* 0 End of pattern */
@@ -1914,10 +1966,15 @@ enum {
OP_EODN, /* 23 End of data or \n at end of data (\Z) */
OP_EOD, /* 24 End of data (\z) */
- 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 */
+ /* Line end assertions */
+
+ OP_DOLL, /* 25 End of line - not multiline */
+ OP_DOLLM, /* 26 End of line - multiline */
+ OP_CIRC, /* 27 Start of line - not multiline */
+ OP_CIRCM, /* 28 Start of line - multiline */
+
+ /* Single characters; caseful must precede the caseless ones */
+
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 */
@@ -1926,7 +1983,7 @@ enum {
/* 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 ****/
+ /* Repeated 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 */
@@ -1944,7 +2001,7 @@ enum {
OP_POSQUERY, /* 44 Posesssified query, caseful */
OP_POSUPTO, /* 45 Possessified upto, caseful */
- /**** Single characters, caseless, must follow the caseful ones */
+ /* Repeated characters; caseless must follow the caseful ones */
OP_STARI, /* 46 */
OP_MINSTARI, /* 47 */
@@ -1962,8 +2019,8 @@ enum {
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 ****/
+ /* The negated ones must follow the non-negated ones, and match them */
+ /* Negated repeated 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 */
@@ -1981,7 +2038,7 @@ enum {
OP_NOTPOSQUERY, /* 70 */
OP_NOTPOSUPTO, /* 71 */
- /**** Negated single character, caseless; must follow the caseful ones ****/
+ /* Negated repeated character, caseless; must follow the caseful ones */
OP_NOTSTARI, /* 72 */
OP_NOTMINSTARI, /* 73 */
@@ -1999,7 +2056,7 @@ enum {
OP_NOTPOSQUERYI, /* 83 */
OP_NOTPOSUPTOI, /* 84 */
- /**** Character types ****/
+ /* Character types */
OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */
OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */
@@ -2030,89 +2087,96 @@ enum {
OP_CRRANGE, /* 104 These are different to the three sets above. */
OP_CRMINRANGE, /* 105 */
+ OP_CRPOSSTAR, /* 106 Possessified versions */
+ OP_CRPOSPLUS, /* 107 */
+ OP_CRPOSQUERY, /* 108 */
+ OP_CRPOSRANGE, /* 109 */
+
/* 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
+ OP_CLASS, /* 110 Match a character class, chars < 256 only */
+ OP_NCLASS, /* 111 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
+ OP_XCLASS, /* 112 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. */
+ OP_REF, /* 113 Match a back reference, casefully */
+ OP_REFI, /* 114 Match a back reference, caselessly */
+ OP_DNREF, /* 115 Match a duplicate name backref, casefully */
+ OP_DNREFI, /* 116 Match a duplicate name backref, caselessly */
+ OP_RECURSE, /* 117 Match a numbered subpattern (possibly recursive) */
+ OP_CALLOUT, /* 118 Call out to external function if provided */
+
+ OP_ALT, /* 119 Start of alternation */
+ OP_KET, /* 120 End of group that doesn't have an unbounded repeat */
+ OP_KETRMAX, /* 121 These two must remain together and in this */
+ OP_KETRMIN, /* 122 order. They are for groups the repeat for ever. */
+ OP_KETRPOS, /* 123 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 */
+ OP_REVERSE, /* 124 Move pointer back - used in lookbehind assertions */
+ OP_ASSERT, /* 125 Positive lookahead */
+ OP_ASSERT_NOT, /* 126 Negative lookahead */
+ OP_ASSERTBACK, /* 127 Positive lookbehind */
+ OP_ASSERTBACK_NOT, /* 128 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 */
+ OP_ONCE, /* 129 Atomic group, contains captures */
+ OP_ONCE_NC, /* 130 Atomic group containing no captures */
+ OP_BRA, /* 131 Start of non-capturing bracket */
+ OP_BRAPOS, /* 132 Ditto, with unlimited, possessive repeat */
+ OP_CBRA, /* 133 Start of capturing bracket */
+ OP_CBRAPOS, /* 134 Ditto, with unlimited, possessive repeat */
+ OP_COND, /* 135 Conditional group */
/* These five must follow the previous five, in the same order. There's a
check for >= SBRA to distinguish the two sets. */
- 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 */
+ OP_SBRA, /* 136 Start of non-capturing bracket, check empty */
+ OP_SBRAPOS, /* 137 Ditto, with unlimited, possessive repeat */
+ OP_SCBRA, /* 138 Start of capturing bracket, check empty */
+ OP_SCBRAPOS, /* 139 Ditto, with unlimited, possessive repeat */
+ OP_SCOND, /* 140 Conditional group, check empty */
/* The next two pairs must (respectively) be kept together. */
- 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_CREF, /* 141 Used to hold a capture number as condition */
+ OP_DNCREF, /* 142 Used to point to duplicate names as a condition */
+ OP_RREF, /* 143 Used to hold a recursion number as condition */
+ OP_DNRREF, /* 144 Used to point to duplicate names as a condition */
+ OP_DEF, /* 145 The DEFINE condition */
- OP_BRAZERO, /* 140 These two must remain together and in this */
- OP_BRAMINZERO, /* 141 order. */
- OP_BRAPOSZERO, /* 142 */
+ OP_BRAZERO, /* 146 These two must remain together and in this */
+ OP_BRAMINZERO, /* 147 order. */
+ OP_BRAPOSZERO, /* 148 */
/* These are backtracking control verbs */
- 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 */
+ OP_MARK, /* 149 always has an argument */
+ OP_PRUNE, /* 150 */
+ OP_PRUNE_ARG, /* 151 same, but with argument */
+ OP_SKIP, /* 152 */
+ OP_SKIP_ARG, /* 153 same, but with argument */
+ OP_THEN, /* 154 */
+ OP_THEN_ARG, /* 155 same, but with argument */
+ OP_COMMIT, /* 156 */
/* These are forced failure and success verbs */
- OP_FAIL, /* 151 */
- OP_ACCEPT, /* 152 */
- OP_ASSERT_ACCEPT, /* 153 Used inside assertions */
- OP_CLOSE, /* 154 Used before OP_ACCEPT to close open captures */
+ OP_FAIL, /* 157 */
+ OP_ACCEPT, /* 158 */
+ OP_ASSERT_ACCEPT, /* 159 Used inside assertions */
+ OP_CLOSE, /* 160 Used before OP_ACCEPT to close open captures */
/* This is used to skip a subpattern with a {0} quantifier */
- OP_SKIPZERO, /* 155 */
+ OP_SKIPZERO, /* 161 */
/* 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
@@ -2123,7 +2187,8 @@ enum {
/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro
definitions that follow must also be updated to match. There are also tables
-called "coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */
+called "opcode_possessify" in pcre_compile.c and "coptable" and "poptable" in
+pcre_dfa_exec.c that must be updated. */
/* This macro defines textual names for all the opcodes. These are used only
@@ -2136,7 +2201,7 @@ some cases doesn't actually use these names at all). */
"\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \
"notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \
"extuni", "\\Z", "\\z", \
- "^", "^", "$", "$", "char", "chari", "not", "noti", \
+ "$", "$", "^", "^", "char", "chari", "not", "noti", \
"*", "*?", "+", "+?", "?", "??", \
"{", "{", "{", \
"*+","++", "?+", "{", \
@@ -2152,7 +2217,8 @@ some cases doesn't actually use these names at all). */
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
"*+","++", "?+", "{", \
"*", "*?", "+", "+?", "?", "??", "{", "{", \
- "class", "nclass", "xclass", "Ref", "Refi", \
+ "*+","++", "?+", "{", \
+ "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \
"Recurse", "Callout", \
"Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \
"Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \
@@ -2161,7 +2227,7 @@ some cases doesn't actually use these names at all). */
"Cond", \
"SBra", "SBraPos", "SCBra", "SCBraPos", \
"SCond", \
- "Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def", \
+ "Cond ref", "Cond dnref", "Cond rec", "Cond dnrec", "Cond def", \
"Brazero", "Braminzero", "Braposzero", \
"*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \
"*THEN", "*THEN", "*COMMIT", "*FAIL", \
@@ -2186,7 +2252,7 @@ in UTF-8 mode. The code that uses this table must know about such things. */
3, 3, /* \P, \p */ \
1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \
1, /* \X */ \
- 1, 1, 1, 1, 1, 1, /* \Z, \z, ^, ^M, $, $M */ \
+ 1, 1, 1, 1, 1, 1, /* \Z, \z, $, $M ^, ^M */ \
2, /* Char - the minimum length */ \
2, /* Chari - the minimum length */ \
2, /* not */ \
@@ -2217,11 +2283,14 @@ in UTF-8 mode. The code that uses this table must know about such things. */
/* Character class & ref repeats */ \
1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \
+ 1, 1, 1, 1+2*IMM2_SIZE, /* Possessive *+, ++, ?+, CRPOSRANGE */ \
1+(32/sizeof(pcre_uchar)), /* CLASS */ \
1+(32/sizeof(pcre_uchar)), /* NCLASS */ \
0, /* XCLASS - variable length */ \
1+IMM2_SIZE, /* REF */ \
1+IMM2_SIZE, /* REFI */ \
+ 1+2*IMM2_SIZE, /* DNREF */ \
+ 1+2*IMM2_SIZE, /* DNREFI */ \
1+LINK_SIZE, /* RECURSE */ \
2+2*LINK_SIZE, /* CALLOUT */ \
1+LINK_SIZE, /* Alt */ \
@@ -2246,8 +2315,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */
1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \
1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \
1+LINK_SIZE, /* SCOND */ \
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* CREF, NCREF */ \
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* RREF, NRREF */ \
+ 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* CREF, DNCREF */ \
+ 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* RREF, DNRREF */ \
1, /* DEF */ \
1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \
3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \
@@ -2256,8 +2325,7 @@ in UTF-8 mode. The code that uses this table must know about such things. */
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. */
+/* A magic value for OP_RREF to indicate the "any recursion" condition. */
#define RREF_ANY 0xffff
@@ -2272,9 +2340,11 @@ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
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, ERR69,
- ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERRCOUNT };
+ ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79,
+ ERR80, ERR81, ERR82, ERR83, ERR84, 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 };
@@ -2282,48 +2352,49 @@ enum { JIT_COMPILE, JIT_PARTIAL_SOFT_COMPILE, JIT_PARTIAL_HARD_COMPILE,
code vector run on as long as necessary after the end. We store an explicit
offset to the name table so that if a regex is compiled on one host, saved, and
then run on another where the size of pointers is different, all might still
-be well. For the case of compiled-on-4 and run-on-8, we include an extra
-pointer that is always NULL. For future-proofing, a few dummy fields were
-originally included - even though you can never get this planning right - but
-there is only one left now.
-
-NOTE NOTE NOTE:
-Because people can now save and re-use compiled patterns, any additions to this
-structure should be made at the end, and something earlier (e.g. a new
-flag in the options or one of the dummy fields) should indicate that the new
-fields are present. Currently PCRE always sets the dummy fields to zero.
-NOTE NOTE NOTE
+be well.
+
+The size of the structure must be a multiple of 8 bytes. For the case of
+compiled-on-4 and run-on-8, we include an extra pointer that is always NULL so
+that there are an even number of pointers which therefore are a multiple of 8
+bytes.
+
+It is necessary to fork the struct for the 32 bit library, since it needs to
+use pcre_uint32 for first_char and req_char. We can't put an ifdef inside the
+typedef because pcretest needs access to the struct of the 8-, 16- and 32-bit
+variants.
+
+*** WARNING ***
+When new fields are added to these structures, remember to adjust the code in
+pcre_byte_order.c that is concerned with swapping the byte order of the fields
+when a compiled regex is reloaded on a host with different endianness.
+*** WARNING ***
+There is also similar byte-flipping code in pcretest.c, which is used for
+testing the byte-flipping features. It must also be kept in step.
+*** WARNING ***
*/
-#if defined COMPILE_PCRE8
-#define REAL_PCRE real_pcre
-#elif defined COMPILE_PCRE16
-#define REAL_PCRE real_pcre16
-#elif defined COMPILE_PCRE32
-#define REAL_PCRE real_pcre32
-#endif
-
-/* It is necessary to fork the struct for 32 bit, since it needs to use
- * pcre_uchar for first_char and req_char. Can't put an ifdef inside the
- * typedef since pcretest needs access to the struct of the 8-, 16-
- * and 32-bit variants. */
-
typedef struct real_pcre8_or_16 {
pcre_uint32 magic_number;
pcre_uint32 size; /* Total that was malloced */
pcre_uint32 options; /* Public options */
- pcre_uint16 flags; /* Private flags */
+ pcre_uint32 flags; /* Private flags */
+ pcre_uint32 limit_match; /* Limit set from regex */
+ pcre_uint32 limit_recursion; /* Limit set from regex */
+ pcre_uint16 first_char; /* Starting character */
+ pcre_uint16 req_char; /* This character must be seen */
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 */
+ pcre_uint16 dummy1; /* To ensure size is a multiple of 8 */
+ pcre_uint16 dummy2; /* To ensure size is a multiple of 8 */
+ pcre_uint16 dummy3; /* To ensure size is a multiple of 8 */
const pcre_uint8 *tables; /* Pointer to tables or NULL for std */
- const pcre_uint8 *nullpad; /* NULL padding */
+ void *nullpad; /* NULL padding */
} real_pcre8_or_16;
typedef struct real_pcre8_or_16 real_pcre;
@@ -2333,22 +2404,31 @@ typedef struct real_pcre32 {
pcre_uint32 magic_number;
pcre_uint32 size; /* Total that was malloced */
pcre_uint32 options; /* Public options */
- pcre_uint16 flags; /* Private flags */
+ pcre_uint32 flags; /* Private flags */
+ pcre_uint32 limit_match; /* Limit set from regex */
+ pcre_uint32 limit_recursion; /* Limit set from regex */
+ pcre_uint32 first_char; /* Starting character */
+ pcre_uint32 req_char; /* This character must be seen */
pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */
pcre_uint16 top_bracket; /* Highest numbered group */
pcre_uint16 top_backref; /* Highest numbered back reference */
- pcre_uint32 first_char; /* Starting character */
- pcre_uint32 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 */
- pcre_uint16 dummy1; /* for later expansion */
- pcre_uint16 dummy2; /* for later expansion */
+ pcre_uint16 dummy; /* To ensure size is a multiple of 8 */
const pcre_uint8 *tables; /* Pointer to tables or NULL for std */
- void *nullpad; /* for later expansion */
+ void *nullpad; /* NULL padding */
} real_pcre32;
+#if defined COMPILE_PCRE8
+#define REAL_PCRE real_pcre
+#elif defined COMPILE_PCRE16
+#define REAL_PCRE real_pcre16
+#elif defined COMPILE_PCRE32
+#define REAL_PCRE real_pcre32
+#endif
+
/* Assert that the size of REAL_PCRE is divisible by 8 */
typedef int __assert_real_pcre_size_divisible_8[(sizeof(REAL_PCRE) % 8) == 0 ? 1 : -1];
@@ -2382,6 +2462,15 @@ typedef struct open_capitem {
pcre_uint16 flag; /* Set TRUE if recursive back ref */
} open_capitem;
+/* Structure for building a list of named groups during the first pass of
+compiling. */
+
+typedef struct named_group {
+ const pcre_uchar *name; /* Points to the name in the pattern */
+ int length; /* Length of the name */
+ pcre_uint32 number; /* Group number */
+} named_group;
+
/* Structure for passing "static" information around between the functions
doing the compiling, so that they are thread-safe. */
@@ -2394,24 +2483,29 @@ typedef struct compile_data {
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 */
+ open_capitem *open_caps; /* Chain of open capture items */
+ named_group *named_groups; /* Points to vector in pre-compile */
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 named_group_list_size; /* Number of entries in the list */
int workspace_size; /* Size of workspace */
- unsigned int bracount; /* Count of capturing parens as we compile */
+ unsigned 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 */
+ unsigned int namedrefcount; /* Number of backreferences by name */
+ int parens_depth; /* Depth of nested parentheses */
int assert_depth; /* Depth of nested assertions */
- int external_options; /* External (initial) options */
- int external_flags; /* External flag bits to be set */
+ pcre_uint32 external_options; /* External (initial) options */
+ pcre_uint32 external_flags; /* External flag bits to be set */
int req_varyopt; /* "After variable item" flag for reqbyte */
BOOL had_accept; /* (*ACCEPT) encountered */
BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
BOOL check_lookbehind; /* Lookbehinds need later checking */
+ BOOL dupnames; /* Duplicate names exist */
int nltype; /* Newline type */
int nllen; /* Newline string length */
pcre_uchar nl[4]; /* Newline string when fixed length */
@@ -2433,6 +2527,7 @@ typedef struct recursion_info {
unsigned 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 */
+ int saved_capture_last; /* Last capture number */
PCRE_PUCHAR subject_position; /* Position at start of recursion */
} recursion_info;
@@ -2469,12 +2564,13 @@ typedef struct match_data {
int nllen; /* Newline string length */
int name_count; /* Number of names in name table */
int name_entry_size; /* Size of entry in names table */
+ unsigned int skip_arg_count; /* For counting SKIP_ARGs */
+ unsigned int ignore_skip_arg; /* For re-run when SKIP arg name not found */
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 */
@@ -2486,7 +2582,6 @@ typedef struct match_data {
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 */
@@ -2495,7 +2590,7 @@ typedef struct match_data {
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 */
+ pcre_int32 capture_last; /* Most recent capture number + overflow flag */
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 */
diff --git a/ext/pcre/pcrelib/pcre_maketables.c b/ext/pcre/pcrelib/pcre_maketables.c
index 610a669586..a44a6eaa90 100644
--- a/ext/pcre/pcrelib/pcre_maketables.c
+++ b/ext/pcre/pcrelib/pcre_maketables.c
@@ -98,13 +98,17 @@ for (i = 0; i < 256; i++) *p++ = tolower(i);
for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);
/* Then the character class tables. Don't try to be clever and save effort on
-exclusive ones - in some locales things may be different. Note that the table
-for "space" includes everything "isspace" gives, including VT in the default
-locale. This makes it work for the POSIX class [:space:]. Note also that it is
-possible for a character to be alnum or alpha without being lower or upper,
-such as "male and female ordinals" (\xAA and \xBA) in the fr_FR locale (at
-least under Debian Linux's locales as of 12/2005). So we must test for alnum
-specially. */
+exclusive ones - in some locales things may be different.
+
+Note that the table for "space" includes everything "isspace" gives, including
+VT in the default locale. This makes it work for the POSIX class [:space:].
+From release 8.34 is is also correct for Perl space, because Perl added VT at
+release 5.18.
+
+Note also that it is possible for a character to be alnum or alpha without
+being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the
+fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must
+test for alnum specially. */
memset(p, 0, cbit_length);
for (i = 0; i < 256; i++)
@@ -123,14 +127,15 @@ for (i = 0; i < 256; i++)
}
p += cbit_length;
-/* Finally, the character type table. In this, we exclude VT from the white
-space chars, because Perl doesn't recognize it as such for \s and for comments
-within regexes. */
+/* Finally, the character type table. In this, we used to exclude VT from the
+white space chars, because Perl didn't recognize it as such for \s and for
+comments within regexes. However, Perl changed at release 5.18, so PCRE changed
+at release 8.34. */
for (i = 0; i < 256; i++)
{
int x = 0;
- if (i != CHAR_VT && isspace(i)) x += ctype_space;
+ if (isspace(i)) x += ctype_space;
if (isalpha(i)) x += ctype_letter;
if (isdigit(i)) x += ctype_digit;
if (isxdigit(i)) x += ctype_xdigit;
diff --git a/ext/pcre/pcrelib/pcre_study.c b/ext/pcre/pcrelib/pcre_study.c
index 12d2a66817..c2aff517a5 100644
--- a/ext/pcre/pcrelib/pcre_study.c
+++ b/ext/pcre/pcrelib/pcre_study.c
@@ -66,8 +66,9 @@ string of that length that matches. In UTF8 mode, the result is in characters
rather than bytes.
Arguments:
+ re compiled pattern block
code pointer to start of group (the bracket)
- startcode pointer to start of the whole pattern
+ startcode pointer to start of the whole pattern's code
options the compiling options
int RECURSE depth
@@ -78,8 +79,8 @@ Returns: the minimum length
*/
static int
-find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options,
- int recurse_depth)
+find_minlength(const REAL_PCRE *re, const pcre_uchar *code,
+ const pcre_uchar *startcode, int options, int recurse_depth)
{
int length = -1;
/* PCRE_UTF16 has the same value as PCRE_UTF8. */
@@ -129,7 +130,7 @@ for (;;)
case OP_SBRAPOS:
case OP_ONCE:
case OP_ONCE_NC:
- d = find_minlength(cc, startcode, options, recurse_depth);
+ d = find_minlength(re, cc, startcode, options, recurse_depth);
if (d < 0) return d;
branchlength += d;
do cc += GET(cc, 1); while (*cc == OP_ALT);
@@ -175,9 +176,9 @@ for (;;)
case OP_REVERSE:
case OP_CREF:
- case OP_NCREF:
+ case OP_DNCREF:
case OP_RREF:
- case OP_NRREF:
+ case OP_DNRREF:
case OP_DEF:
case OP_CALLOUT:
case OP_SOD:
@@ -341,6 +342,7 @@ for (;;)
{
case OP_CRPLUS:
case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
branchlength++;
/* Fall through */
@@ -348,11 +350,14 @@ for (;;)
case OP_CRMINSTAR:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
cc++;
break;
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
branchlength += GET2(cc,1);
cc += 1 + 2 * IMM2_SIZE;
break;
@@ -375,7 +380,38 @@ for (;;)
matches an empty string (by default it causes a matching failure), so in
that case we must set the minimum length to zero. */
- case OP_REF:
+ case OP_DNREF: /* Duplicate named pattern back reference */
+ case OP_DNREFI:
+ if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
+ {
+ int count = GET2(cc, 1+IMM2_SIZE);
+ pcre_uchar *slot = (pcre_uchar *)re +
+ re->name_table_offset + GET2(cc, 1) * re->name_entry_size;
+ d = INT_MAX;
+ while (count-- > 0)
+ {
+ ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(slot, 0));
+ if (cs == NULL) return -2;
+ do ce += GET(ce, 1); while (*ce == OP_ALT);
+ if (cc > cs && cc < ce)
+ {
+ d = 0;
+ had_recurse = TRUE;
+ break;
+ }
+ else
+ {
+ int dd = find_minlength(re, cs, startcode, options, recurse_depth);
+ if (dd < d) d = dd;
+ }
+ slot += re->name_entry_size;
+ }
+ }
+ else d = 0;
+ cc += 1 + 2*IMM2_SIZE;
+ goto REPEAT_BACK_REFERENCE;
+
+ case OP_REF: /* Single back reference */
case OP_REFI:
if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
{
@@ -389,7 +425,7 @@ for (;;)
}
else
{
- d = find_minlength(cs, startcode, options, recurse_depth);
+ d = find_minlength(re, cs, startcode, options, recurse_depth);
}
}
else d = 0;
@@ -397,24 +433,29 @@ for (;;)
/* Handle repeated back references */
+ REPEAT_BACK_REFERENCE:
switch (*cc)
{
case OP_CRSTAR:
case OP_CRMINSTAR:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
min = 0;
cc++;
break;
case OP_CRPLUS:
case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
min = 1;
cc++;
break;
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
min = GET2(cc, 1);
cc += 1 + 2 * IMM2_SIZE;
break;
@@ -437,7 +478,8 @@ for (;;)
had_recurse = TRUE;
else
{
- branchlength += find_minlength(cs, startcode, options, recurse_depth + 1);
+ branchlength += find_minlength(re, cs, startcode, options,
+ recurse_depth + 1);
}
cc += 1 + LINK_SIZE;
break;
@@ -778,6 +820,10 @@ do
case OP_COND:
case OP_CREF:
case OP_DEF:
+ case OP_DNCREF:
+ case OP_DNREF:
+ case OP_DNREFI:
+ case OP_DNRREF:
case OP_DOLL:
case OP_DOLLM:
case OP_END:
@@ -786,7 +832,6 @@ do
case OP_EXTUNI:
case OP_FAIL:
case OP_MARK:
- case OP_NCREF:
case OP_NOT:
case OP_NOTEXACT:
case OP_NOTEXACTI:
@@ -818,7 +863,6 @@ do
case OP_NOTUPTOI:
case OP_NOT_HSPACE:
case OP_NOT_VSPACE:
- case OP_NRREF:
case OP_PROP:
case OP_PRUNE:
case OP_PRUNE_ARG:
@@ -1183,24 +1227,16 @@ do
set_type_bits(start_bits, cbit_digit, table_limit, cd);
break;
- /* The cbit_space table has vertical tab as whitespace; we have to
- ensure it gets set as not whitespace. Luckily, the code value is the
- same (0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate
- bit. */
+ /* The cbit_space table has vertical tab as whitespace; we no longer
+ have to play fancy tricks because Perl added VT to its whitespace at
+ release 5.18. PCRE added it at release 8.34. */
case OP_NOT_WHITESPACE:
set_nottype_bits(start_bits, cbit_space, table_limit, cd);
- start_bits[1] |= 0x08;
break;
- /* The cbit_space table has vertical tab as whitespace; we have to
- avoid setting it. Luckily, the code value is the same (0x0b) in ASCII
- and EBCDIC, so we can just adjust the appropriate bit. */
-
case OP_WHITESPACE:
- c = start_bits[1]; /* Save in case it was already set */
set_type_bits(start_bits, cbit_space, table_limit, cd);
- start_bits[1] = (start_bits[1] & ~0x08) | c;
break;
case OP_NOT_WORDCHAR:
@@ -1277,11 +1313,14 @@ do
case OP_CRMINSTAR:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
tcode++;
break;
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;
else try_next = FALSE;
break;
@@ -1346,6 +1385,7 @@ pcre_uchar *code;
compile_data compile_block;
const REAL_PCRE *re = (const REAL_PCRE *)external_re;
+
*errorptr = NULL;
if (re == NULL || re->magic_number != MAGIC_NUMBER)
@@ -1422,7 +1462,7 @@ if ((re->options & PCRE_ANCHORED) == 0 &&
/* Find the minimum length of subject string. */
-switch(min = find_minlength(code, code, re->options, 0))
+switch(min = find_minlength(re, 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;
diff --git a/ext/pcre/pcrelib/pcre_tables.c b/ext/pcre/pcrelib/pcre_tables.c
index 34ee0488a8..f38ab52cbb 100644
--- a/ext/pcre/pcrelib/pcre_tables.c
+++ b/ext/pcre/pcrelib/pcre_tables.c
@@ -346,6 +346,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
#define STRING_Xan0 STR_X STR_a STR_n "\0"
#define STRING_Xps0 STR_X STR_p STR_s "\0"
#define STRING_Xsp0 STR_X STR_s STR_p "\0"
+#define STRING_Xuc0 STR_X STR_u STR_c "\0"
#define STRING_Xwd0 STR_X STR_w STR_d "\0"
#define STRING_Yi0 STR_Y STR_i "\0"
#define STRING_Z0 STR_Z "\0"
@@ -493,6 +494,7 @@ const char PRIV(utt_names)[] =
STRING_Xan0
STRING_Xps0
STRING_Xsp0
+ STRING_Xuc0
STRING_Xwd0
STRING_Yi0
STRING_Z0
@@ -640,12 +642,13 @@ const ucp_type_table PRIV(utt)[] = {
{ 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 }
+ { 1023, PT_UCNC, 0 },
+ { 1027, PT_WORD, 0 },
+ { 1031, PT_SC, ucp_Yi },
+ { 1034, PT_GC, ucp_Z },
+ { 1036, PT_PC, ucp_Zl },
+ { 1039, PT_PC, ucp_Zp },
+ { 1042, PT_PC, ucp_Zs }
};
const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
diff --git a/ext/pcre/pcrelib/pcre_ucd.c b/ext/pcre/pcrelib/pcre_ucd.c
index 56f31a1e69..46ea70c44c 100644
--- a/ext/pcre/pcrelib/pcre_ucd.c
+++ b/ext/pcre/pcrelib/pcre_ucd.c
@@ -20,7 +20,7 @@ needed. */
/* Unicode character database. */
/* This file was autogenerated by the MultiStage2.py script. */
-/* Total size: 65696 bytes, block size: 128. */
+/* Total size: 65688 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
@@ -79,7 +79,7 @@ const pcre_uint32 PRIV(ucd_caseless_sets)[] = {
#ifndef PCRE_INCLUDED
-const ucd_record PRIV(ucd_records)[] = { /* 5024 bytes, record size 8 */
+const ucd_record PRIV(ucd_records)[] = { /* 5016 bytes, record size 8 */
{ 9, 0, 2, 0, 0, }, /* 0 */
{ 9, 0, 1, 0, 0, }, /* 1 */
{ 9, 0, 0, 0, 0, }, /* 2 */
@@ -422,7 +422,7 @@ const ucd_record PRIV(ucd_records)[] = { /* 5024 bytes, record size 8 */
{ 37, 21, 12, 0, 0, }, /* 339 */
{ 37, 17, 12, 0, 0, }, /* 340 */
{ 37, 12, 3, 0, 0, }, /* 341 */
- { 37, 29, 12, 0, 0, }, /* 342 */
+ { 37, 1, 2, 0, 0, }, /* 342 */
{ 37, 13, 12, 0, 0, }, /* 343 */
{ 37, 7, 12, 0, 0, }, /* 344 */
{ 37, 6, 12, 0, 0, }, /* 345 */
@@ -598,116 +598,115 @@ const ucd_record PRIV(ucd_records)[] = { /* 5024 bytes, record size 8 */
{ 83, 10, 5, 0, 0, }, /* 515 */
{ 83, 7, 12, 0, 0, }, /* 516 */
{ 83, 21, 12, 0, 0, }, /* 517 */
- { 83, 6, 12, 0, 0, }, /* 518 */
- { 83, 13, 12, 0, 0, }, /* 519 */
- { 67, 7, 12, 0, 0, }, /* 520 */
- { 67, 12, 3, 0, 0, }, /* 521 */
- { 67, 10, 5, 0, 0, }, /* 522 */
- { 67, 13, 12, 0, 0, }, /* 523 */
- { 67, 21, 12, 0, 0, }, /* 524 */
- { 38, 6, 12, 0, 0, }, /* 525 */
- { 91, 7, 12, 0, 0, }, /* 526 */
- { 91, 12, 3, 0, 0, }, /* 527 */
- { 91, 6, 12, 0, 0, }, /* 528 */
- { 91, 21, 12, 0, 0, }, /* 529 */
- { 86, 7, 12, 0, 0, }, /* 530 */
- { 86, 10, 5, 0, 0, }, /* 531 */
- { 86, 12, 3, 0, 0, }, /* 532 */
- { 86, 21, 12, 0, 0, }, /* 533 */
- { 86, 6, 12, 0, 0, }, /* 534 */
- { 86, 13, 12, 0, 0, }, /* 535 */
- { 23, 7, 9, 0, 0, }, /* 536 */
- { 23, 7, 10, 0, 0, }, /* 537 */
- { 9, 4, 2, 0, 0, }, /* 538 */
- { 9, 3, 12, 0, 0, }, /* 539 */
- { 25, 25, 12, 0, 0, }, /* 540 */
- { 0, 24, 12, 0, 0, }, /* 541 */
- { 9, 6, 3, 0, 0, }, /* 542 */
- { 35, 7, 12, 0, 0, }, /* 543 */
- { 19, 14, 12, 0, 0, }, /* 544 */
- { 19, 15, 12, 0, 0, }, /* 545 */
- { 19, 26, 12, 0, 0, }, /* 546 */
- { 70, 7, 12, 0, 0, }, /* 547 */
- { 66, 7, 12, 0, 0, }, /* 548 */
- { 41, 7, 12, 0, 0, }, /* 549 */
- { 41, 15, 12, 0, 0, }, /* 550 */
- { 18, 7, 12, 0, 0, }, /* 551 */
- { 18, 14, 12, 0, 0, }, /* 552 */
- { 59, 7, 12, 0, 0, }, /* 553 */
- { 59, 21, 12, 0, 0, }, /* 554 */
- { 42, 7, 12, 0, 0, }, /* 555 */
- { 42, 21, 12, 0, 0, }, /* 556 */
- { 42, 14, 12, 0, 0, }, /* 557 */
- { 13, 9, 12, 0, 40, }, /* 558 */
- { 13, 5, 12, 0, -40, }, /* 559 */
- { 46, 7, 12, 0, 0, }, /* 560 */
- { 44, 7, 12, 0, 0, }, /* 561 */
- { 44, 13, 12, 0, 0, }, /* 562 */
- { 11, 7, 12, 0, 0, }, /* 563 */
- { 80, 7, 12, 0, 0, }, /* 564 */
- { 80, 21, 12, 0, 0, }, /* 565 */
- { 80, 15, 12, 0, 0, }, /* 566 */
- { 65, 7, 12, 0, 0, }, /* 567 */
- { 65, 15, 12, 0, 0, }, /* 568 */
- { 65, 21, 12, 0, 0, }, /* 569 */
- { 71, 7, 12, 0, 0, }, /* 570 */
- { 71, 21, 12, 0, 0, }, /* 571 */
- { 97, 7, 12, 0, 0, }, /* 572 */
- { 96, 7, 12, 0, 0, }, /* 573 */
- { 30, 7, 12, 0, 0, }, /* 574 */
- { 30, 12, 3, 0, 0, }, /* 575 */
- { 30, 15, 12, 0, 0, }, /* 576 */
- { 30, 21, 12, 0, 0, }, /* 577 */
- { 87, 7, 12, 0, 0, }, /* 578 */
- { 87, 15, 12, 0, 0, }, /* 579 */
- { 87, 21, 12, 0, 0, }, /* 580 */
- { 77, 7, 12, 0, 0, }, /* 581 */
- { 77, 21, 12, 0, 0, }, /* 582 */
- { 82, 7, 12, 0, 0, }, /* 583 */
- { 82, 15, 12, 0, 0, }, /* 584 */
- { 81, 7, 12, 0, 0, }, /* 585 */
- { 81, 15, 12, 0, 0, }, /* 586 */
- { 88, 7, 12, 0, 0, }, /* 587 */
- { 0, 15, 12, 0, 0, }, /* 588 */
- { 93, 10, 5, 0, 0, }, /* 589 */
- { 93, 12, 3, 0, 0, }, /* 590 */
- { 93, 7, 12, 0, 0, }, /* 591 */
- { 93, 21, 12, 0, 0, }, /* 592 */
- { 93, 15, 12, 0, 0, }, /* 593 */
- { 93, 13, 12, 0, 0, }, /* 594 */
- { 84, 12, 3, 0, 0, }, /* 595 */
- { 84, 10, 5, 0, 0, }, /* 596 */
- { 84, 7, 12, 0, 0, }, /* 597 */
- { 84, 21, 12, 0, 0, }, /* 598 */
- { 84, 1, 2, 0, 0, }, /* 599 */
- { 100, 7, 12, 0, 0, }, /* 600 */
- { 100, 13, 12, 0, 0, }, /* 601 */
- { 95, 12, 3, 0, 0, }, /* 602 */
- { 95, 7, 12, 0, 0, }, /* 603 */
- { 95, 10, 5, 0, 0, }, /* 604 */
- { 95, 13, 12, 0, 0, }, /* 605 */
- { 95, 21, 12, 0, 0, }, /* 606 */
- { 99, 12, 3, 0, 0, }, /* 607 */
- { 99, 10, 5, 0, 0, }, /* 608 */
- { 99, 7, 12, 0, 0, }, /* 609 */
- { 99, 21, 12, 0, 0, }, /* 610 */
- { 99, 13, 12, 0, 0, }, /* 611 */
- { 101, 7, 12, 0, 0, }, /* 612 */
- { 101, 12, 3, 0, 0, }, /* 613 */
- { 101, 10, 5, 0, 0, }, /* 614 */
- { 101, 13, 12, 0, 0, }, /* 615 */
- { 62, 7, 12, 0, 0, }, /* 616 */
- { 62, 14, 12, 0, 0, }, /* 617 */
- { 62, 21, 12, 0, 0, }, /* 618 */
- { 79, 7, 12, 0, 0, }, /* 619 */
- { 98, 7, 12, 0, 0, }, /* 620 */
- { 98, 10, 5, 0, 0, }, /* 621 */
- { 98, 12, 3, 0, 0, }, /* 622 */
- { 98, 6, 12, 0, 0, }, /* 623 */
- { 9, 10, 3, 0, 0, }, /* 624 */
- { 19, 12, 3, 0, 0, }, /* 625 */
- { 9, 26, 11, 0, 0, }, /* 626 */
- { 26, 26, 12, 0, 0, }, /* 627 */
+ { 83, 13, 12, 0, 0, }, /* 518 */
+ { 67, 7, 12, 0, 0, }, /* 519 */
+ { 67, 12, 3, 0, 0, }, /* 520 */
+ { 67, 10, 5, 0, 0, }, /* 521 */
+ { 67, 13, 12, 0, 0, }, /* 522 */
+ { 67, 21, 12, 0, 0, }, /* 523 */
+ { 38, 6, 12, 0, 0, }, /* 524 */
+ { 91, 7, 12, 0, 0, }, /* 525 */
+ { 91, 12, 3, 0, 0, }, /* 526 */
+ { 91, 6, 12, 0, 0, }, /* 527 */
+ { 91, 21, 12, 0, 0, }, /* 528 */
+ { 86, 7, 12, 0, 0, }, /* 529 */
+ { 86, 10, 5, 0, 0, }, /* 530 */
+ { 86, 12, 3, 0, 0, }, /* 531 */
+ { 86, 21, 12, 0, 0, }, /* 532 */
+ { 86, 6, 12, 0, 0, }, /* 533 */
+ { 86, 13, 12, 0, 0, }, /* 534 */
+ { 23, 7, 9, 0, 0, }, /* 535 */
+ { 23, 7, 10, 0, 0, }, /* 536 */
+ { 9, 4, 2, 0, 0, }, /* 537 */
+ { 9, 3, 12, 0, 0, }, /* 538 */
+ { 25, 25, 12, 0, 0, }, /* 539 */
+ { 0, 24, 12, 0, 0, }, /* 540 */
+ { 9, 6, 3, 0, 0, }, /* 541 */
+ { 35, 7, 12, 0, 0, }, /* 542 */
+ { 19, 14, 12, 0, 0, }, /* 543 */
+ { 19, 15, 12, 0, 0, }, /* 544 */
+ { 19, 26, 12, 0, 0, }, /* 545 */
+ { 70, 7, 12, 0, 0, }, /* 546 */
+ { 66, 7, 12, 0, 0, }, /* 547 */
+ { 41, 7, 12, 0, 0, }, /* 548 */
+ { 41, 15, 12, 0, 0, }, /* 549 */
+ { 18, 7, 12, 0, 0, }, /* 550 */
+ { 18, 14, 12, 0, 0, }, /* 551 */
+ { 59, 7, 12, 0, 0, }, /* 552 */
+ { 59, 21, 12, 0, 0, }, /* 553 */
+ { 42, 7, 12, 0, 0, }, /* 554 */
+ { 42, 21, 12, 0, 0, }, /* 555 */
+ { 42, 14, 12, 0, 0, }, /* 556 */
+ { 13, 9, 12, 0, 40, }, /* 557 */
+ { 13, 5, 12, 0, -40, }, /* 558 */
+ { 46, 7, 12, 0, 0, }, /* 559 */
+ { 44, 7, 12, 0, 0, }, /* 560 */
+ { 44, 13, 12, 0, 0, }, /* 561 */
+ { 11, 7, 12, 0, 0, }, /* 562 */
+ { 80, 7, 12, 0, 0, }, /* 563 */
+ { 80, 21, 12, 0, 0, }, /* 564 */
+ { 80, 15, 12, 0, 0, }, /* 565 */
+ { 65, 7, 12, 0, 0, }, /* 566 */
+ { 65, 15, 12, 0, 0, }, /* 567 */
+ { 65, 21, 12, 0, 0, }, /* 568 */
+ { 71, 7, 12, 0, 0, }, /* 569 */
+ { 71, 21, 12, 0, 0, }, /* 570 */
+ { 97, 7, 12, 0, 0, }, /* 571 */
+ { 96, 7, 12, 0, 0, }, /* 572 */
+ { 30, 7, 12, 0, 0, }, /* 573 */
+ { 30, 12, 3, 0, 0, }, /* 574 */
+ { 30, 15, 12, 0, 0, }, /* 575 */
+ { 30, 21, 12, 0, 0, }, /* 576 */
+ { 87, 7, 12, 0, 0, }, /* 577 */
+ { 87, 15, 12, 0, 0, }, /* 578 */
+ { 87, 21, 12, 0, 0, }, /* 579 */
+ { 77, 7, 12, 0, 0, }, /* 580 */
+ { 77, 21, 12, 0, 0, }, /* 581 */
+ { 82, 7, 12, 0, 0, }, /* 582 */
+ { 82, 15, 12, 0, 0, }, /* 583 */
+ { 81, 7, 12, 0, 0, }, /* 584 */
+ { 81, 15, 12, 0, 0, }, /* 585 */
+ { 88, 7, 12, 0, 0, }, /* 586 */
+ { 0, 15, 12, 0, 0, }, /* 587 */
+ { 93, 10, 5, 0, 0, }, /* 588 */
+ { 93, 12, 3, 0, 0, }, /* 589 */
+ { 93, 7, 12, 0, 0, }, /* 590 */
+ { 93, 21, 12, 0, 0, }, /* 591 */
+ { 93, 15, 12, 0, 0, }, /* 592 */
+ { 93, 13, 12, 0, 0, }, /* 593 */
+ { 84, 12, 3, 0, 0, }, /* 594 */
+ { 84, 10, 5, 0, 0, }, /* 595 */
+ { 84, 7, 12, 0, 0, }, /* 596 */
+ { 84, 21, 12, 0, 0, }, /* 597 */
+ { 84, 1, 2, 0, 0, }, /* 598 */
+ { 100, 7, 12, 0, 0, }, /* 599 */
+ { 100, 13, 12, 0, 0, }, /* 600 */
+ { 95, 12, 3, 0, 0, }, /* 601 */
+ { 95, 7, 12, 0, 0, }, /* 602 */
+ { 95, 10, 5, 0, 0, }, /* 603 */
+ { 95, 13, 12, 0, 0, }, /* 604 */
+ { 95, 21, 12, 0, 0, }, /* 605 */
+ { 99, 12, 3, 0, 0, }, /* 606 */
+ { 99, 10, 5, 0, 0, }, /* 607 */
+ { 99, 7, 12, 0, 0, }, /* 608 */
+ { 99, 21, 12, 0, 0, }, /* 609 */
+ { 99, 13, 12, 0, 0, }, /* 610 */
+ { 101, 7, 12, 0, 0, }, /* 611 */
+ { 101, 12, 3, 0, 0, }, /* 612 */
+ { 101, 10, 5, 0, 0, }, /* 613 */
+ { 101, 13, 12, 0, 0, }, /* 614 */
+ { 62, 7, 12, 0, 0, }, /* 615 */
+ { 62, 14, 12, 0, 0, }, /* 616 */
+ { 62, 21, 12, 0, 0, }, /* 617 */
+ { 79, 7, 12, 0, 0, }, /* 618 */
+ { 98, 7, 12, 0, 0, }, /* 619 */
+ { 98, 10, 5, 0, 0, }, /* 620 */
+ { 98, 12, 3, 0, 0, }, /* 621 */
+ { 98, 6, 12, 0, 0, }, /* 622 */
+ { 9, 10, 3, 0, 0, }, /* 623 */
+ { 19, 12, 3, 0, 0, }, /* 624 */
+ { 9, 26, 11, 0, 0, }, /* 625 */
+ { 26, 26, 12, 0, 0, }, /* 626 */
};
const pcre_uint8 PRIV(ucd_stage1)[] = { /* 8704 bytes */
@@ -1380,7 +1379,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
/* block 12 */
185,185,185,185,185,109,186,186,186,187,187,188, 4,187,189,189,
-190,190,190,190,190,190,190,190,190,190,190, 4,109,109,187, 4,
+190,190,190,190,190,190,190,190,190,190,190, 4,185,109,187, 4,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
102,191,191,191,191,191,191,191,191,191,191,104,104,104,104,104,
@@ -1760,7 +1759,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
/* block 50 */
360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,361,361,362,362,362,109,109,363,363,
+360,360,360,360,360,360,360,361,361,362,362,361,109,109,363,363,
364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
@@ -1885,7 +1884,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
4, 4, 4, 4, 4, 4, 4, 4, 4, 21, 25, 4, 4, 4, 4, 15,
15, 4, 4, 4, 8, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 8, 4, 15, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
- 22, 22, 22, 22, 22,426,426,426,426,426, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22,426, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
23,101,109,109, 23, 23, 23, 23, 23, 23, 8, 8, 8, 6, 7,101,
/* block 63 */
@@ -1929,7 +1928,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
/* block 67 */
- 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 6, 7, 6, 7, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
8, 8, 19, 19, 19, 19, 19, 19, 19, 6, 7, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
@@ -2353,30 +2352,30 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
516,516,516,514,515,515,514,514,514,514,515,515,514,515,515,515,
-515,517,517,517,517,517,517,517,517,517,517,517,517,517,109,518,
-519,519,519,519,519,519,519,519,519,519,109,109,109,109,517,517,
+515,517,517,517,517,517,517,517,517,517,517,517,517,517,109,102,
+518,518,518,518,518,518,518,518,518,518,109,109,109,109,517,517,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 110 */
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,521,521,521,521,521,521,522,
-522,521,521,522,522,521,521,109,109,109,109,109,109,109,109,109,
-520,520,520,521,520,520,520,520,520,520,520,520,521,522,109,109,
-523,523,523,523,523,523,523,523,523,523,109,109,524,524,524,524,
+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,519,519,519,
+519,519,519,519,519,519,519,519,519,520,520,520,520,520,520,521,
+521,520,520,521,521,520,520,109,109,109,109,109,109,109,109,109,
+519,519,519,520,519,519,519,519,519,519,519,519,520,521,109,109,
+522,522,522,522,522,522,522,522,522,522,109,109,523,523,523,523,
295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,
-525,295,295,295,295,295,295,301,301,301,295,296,109,109,109,109,
+524,295,295,295,295,295,295,301,301,301,295,296,109,109,109,109,
/* block 111 */
-526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,
-526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,
-526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,
-527,526,527,527,527,526,526,527,527,526,526,526,526,526,527,527,
-526,527,526,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,526,526,528,529,529,
-530,530,530,530,530,530,530,530,530,530,530,531,532,532,531,531,
-533,533,530,534,534,531,532,109,109,109,109,109,109,109,109,109,
+525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,
+525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,
+525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,
+526,525,526,526,526,525,525,526,526,525,525,525,525,525,526,526,
+525,526,525,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,525,525,527,528,528,
+529,529,529,529,529,529,529,529,529,529,529,530,531,531,530,530,
+532,532,529,533,533,530,531,109,109,109,109,109,109,109,109,109,
/* block 112 */
109,308,308,308,308,308,308,109,109,308,308,308,308,308,308,109,
@@ -2393,85 +2392,85 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
-530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
-530,530,530,531,531,532,531,531,532,531,531,533,531,532,109,109,
-535,535,535,535,535,535,535,535,535,535,109,109,109,109,109,109,
+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,529,
+529,529,529,530,530,531,530,530,531,530,530,532,530,531,109,109,
+534,534,534,534,534,534,534,534,534,534,109,109,109,109,109,109,
/* block 114 */
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
/* block 115 */
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
/* block 116 */
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
/* block 117 */
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
/* block 118 */
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
/* block 119 */
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
/* block 120 */
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
/* block 121 */
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,109,109,109,109,109,109,109,109,109,109,109,109,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,109,109,109,109,109,109,109,109,109,109,109,109,
306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,
306,306,306,306,306,306,306,109,109,109,109,307,307,307,307,307,
307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,
@@ -2479,6 +2478,16 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
307,307,307,307,307,307,307,307,307,307,307,307,109,109,109,109,
/* block 122 */
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+
+/* block 123 */
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,538,538,538,
@@ -2488,16 +2497,6 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
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,
-/* block 123 */
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-
/* block 124 */
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,
@@ -2521,7 +2520,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
/* block 126 */
33, 33, 33, 33, 33, 33, 33,109,109,109,109,109,109,109,109,109,
109,109,109,178,178,178,178,178,109,109,109,109,109,184,181,184,
-184,184,184,184,184,184,184,184,184,540,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,539,184,184,184,184,184,184,
184,184,184,184,184,184,184,109,184,184,184,184,184,109,184,109,
184,184,109,184,184,109,184,184,184,184,184,184,184,184,184,184,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
@@ -2532,8 +2531,8 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,541,541,541,541,541,541,541,541,541,541,541,541,541,541,
-541,541,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+191,191,540,540,540,540,540,540,540,540,540,540,540,540,540,540,
+540,540,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,191,191,191,191,191,191,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
@@ -2600,7 +2599,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
/* block 134 */
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,542,542,
+469,469,469,469,469,469,469,469,469,469,469,469,469,469,541,541,
472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,
472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,109,
109,109,472,472,472,472,472,472,109,109,472,472,472,472,472,472,
@@ -2609,37 +2608,37 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
426,426,426,426,426,426,426,426,426, 22, 22, 22, 19, 19,109,109,
/* block 135 */
-543,543,543,543,543,543,543,543,543,543,543,543,109,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,109,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,109,543,543,109,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,109,109,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,109,109,
+542,542,542,542,542,542,542,542,542,542,542,542,109,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,109,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,109,542,542,109,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,109,109,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 136 */
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,109,109,109,109,109,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,109,109,109,109,109,
/* block 137 */
4, 4, 4,109,109,109,109, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23,109,109,109, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-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,544,544,544,544,544,544,544,544,544,544,544,544,
-544,544,544,544,544,545,545,545,545,546,546,546,546,546,546,546,
+543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
+543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
+543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
+543,543,543,543,543,544,544,544,544,545,545,545,545,545,545,545,
/* block 138 */
-546,546,546,546,546,546,546,546,546,546,545,109,109,109,109,109,
+545,545,545,545,545,545,545,545,545,545,544,109,109,109,109,109,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -2649,49 +2648,49 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,104,109,109,
/* block 139 */
+546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
+546,546,546,546,546,546,546,546,546,546,546,546,546,109,109,109,
547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,
-547,547,547,547,547,547,547,547,547,547,547,547,547,109,109,109,
-548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
-548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
-548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
-548,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,
+547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,
+547,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 140 */
-549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,
-549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,109,
-550,550,550,550,109,109,109,109,109,109,109,109,109,109,109,109,
-551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,
-551,552,551,551,551,551,551,551,551,551,552,109,109,109,109,109,
+548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
+548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,109,
+549,549,549,549,109,109,109,109,109,109,109,109,109,109,109,109,
+550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,
+550,551,550,550,550,550,550,550,550,550,551,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 141 */
-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,109,554,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,109,109,109,109,555,555,555,555,555,555,555,555,
-556,557,557,557,557,557,109,109,109,109,109,109,109,109,109,109,
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,109,553,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,109,109,109,109,554,554,554,554,554,554,554,554,
+555,556,556,556,556,556,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 142 */
+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,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,559,559,559,559,559,559,559,559,
559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,
559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,
-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,
+559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,
/* block 143 */
-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,109,109,
-562,562,562,562,562,562,562,562,562,562,109,109,109,109,109,109,
+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,109,109,
+561,561,561,561,561,561,561,561,561,561,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -2699,61 +2698,61 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 144 */
-563,563,563,563,563,563,109,109,563,109,563,563,563,563,563,563,
+562,562,562,562,562,562,109,109,562,109,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,109,562,562,109,109,109,562,109,109,562,
563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563,563,563,563,563,563,109,563,563,109,109,109,563,109,109,563,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,109,565,566,566,566,566,566,566,566,566,
+563,563,563,563,563,563,109,564,565,565,565,565,565,565,565,565,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 145 */
-567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,
-567,567,567,567,567,567,568,568,568,568,568,568,109,109,109,569,
-570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,
-570,570,570,570,570,570,570,570,570,570,109,109,109,109,109,571,
+566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,
+566,566,566,566,566,566,567,567,567,567,567,567,109,109,109,568,
+569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
+569,569,569,569,569,569,569,569,569,569,109,109,109,109,109,570,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 146 */
+571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
+571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
-572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
-573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
-573,573,573,573,573,573,573,573,109,109,109,109,109,109,573,573,
+572,572,572,572,572,572,572,572,109,109,109,109,109,109,572,572,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 147 */
-574,575,575,575,109,575,575,109,109,109,109,109,575,575,575,575,
-574,574,574,574,109,574,574,574,109,574,574,574,574,574,574,574,
-574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,
-574,574,574,574,109,109,109,109,575,575,575,109,109,109,109,575,
-576,576,576,576,576,576,576,576,109,109,109,109,109,109,109,109,
-577,577,577,577,577,577,577,577,577,109,109,109,109,109,109,109,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,579,579,580,
+573,574,574,574,109,574,574,109,109,109,109,109,574,574,574,574,
+573,573,573,573,109,573,573,573,109,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,109,109,109,109,574,574,574,109,109,109,109,574,
+575,575,575,575,575,575,575,575,109,109,109,109,109,109,109,109,
+576,576,576,576,576,576,576,576,576,109,109,109,109,109,109,109,
+577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
+577,577,577,577,577,577,577,577,577,577,577,577,577,578,578,579,
/* block 148 */
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,109,109,109,582,582,582,582,582,582,582,
-583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,
-583,583,583,583,583,583,109,109,584,584,584,584,584,584,584,584,
-585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,
-585,585,585,109,109,109,109,109,586,586,586,586,586,586,586,586,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,109,109,109,581,581,581,581,581,581,581,
+582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,
+582,582,582,582,582,582,109,109,583,583,583,583,583,583,583,583,
+584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
+584,584,584,109,109,109,109,109,585,585,585,585,585,585,585,585,
/* block 149 */
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,109,109,109,109,109,109,109,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -2765,103 +2764,103 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,
-588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,109,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,109,
/* block 151 */
-589,590,589,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,591,591,590,590,590,590,590,590,590,590,
-590,590,590,590,590,590,590,592,592,592,592,592,592,592,109,109,
-109,109,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
-593,593,593,593,593,593,594,594,594,594,594,594,594,594,594,594,
+588,589,588,590,590,590,590,590,590,590,590,590,590,590,590,590,
+590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,
+590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,
+590,590,590,590,590,590,590,590,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,591,591,591,591,591,591,591,109,109,
+109,109,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
+592,592,592,592,592,592,593,593,593,593,593,593,593,593,593,593,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 152 */
-595,595,596,597,597,597,597,597,597,597,597,597,597,597,597,597,
-597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,
-597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,
-596,596,596,595,595,595,595,596,596,595,595,598,598,599,598,598,
-598,598,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
-600,600,600,600,600,600,600,600,600,109,109,109,109,109,109,109,
-601,601,601,601,601,601,601,601,601,601,109,109,109,109,109,109,
+594,594,595,596,596,596,596,596,596,596,596,596,596,596,596,596,
+596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,
+596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,
+595,595,595,594,594,594,594,595,595,594,594,597,597,598,597,597,
+597,597,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,
+599,599,599,599,599,599,599,599,599,109,109,109,109,109,109,109,
+600,600,600,600,600,600,600,600,600,600,109,109,109,109,109,109,
/* block 153 */
-602,602,602,603,603,603,603,603,603,603,603,603,603,603,603,603,
-603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,
-603,603,603,603,603,603,603,602,602,602,602,602,604,602,602,602,
-602,602,602,602,602,109,605,605,605,605,605,605,605,605,605,605,
-606,606,606,606,109,109,109,109,109,109,109,109,109,109,109,109,
+601,601,601,602,602,602,602,602,602,602,602,602,602,602,602,602,
+602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,
+602,602,602,602,602,602,602,601,601,601,601,601,603,601,601,601,
+601,601,601,601,601,109,604,604,604,604,604,604,604,604,604,604,
+605,605,605,605,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 154 */
-607,607,608,609,609,609,609,609,609,609,609,609,609,609,609,609,
-609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,
-609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,
-609,609,609,608,608,608,607,607,607,607,607,607,607,607,607,608,
-608,609,609,609,609,610,610,610,610,109,109,109,109,109,109,109,
-611,611,611,611,611,611,611,611,611,611,109,109,109,109,109,109,
+606,606,607,608,608,608,608,608,608,608,608,608,608,608,608,608,
+608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,
+608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,
+608,608,608,607,607,607,606,606,606,606,606,606,606,606,606,607,
+607,608,608,608,608,609,609,609,609,109,109,109,109,109,109,109,
+610,610,610,610,610,610,610,610,610,610,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 155 */
-612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,
-612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,
-612,612,612,612,612,612,612,612,612,612,612,613,614,613,614,614,
-613,613,613,613,613,613,614,613,109,109,109,109,109,109,109,109,
-615,615,615,615,615,615,615,615,615,615,109,109,109,109,109,109,
+611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,
+611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,
+611,611,611,611,611,611,611,611,611,611,611,612,613,612,613,613,
+612,612,612,612,612,612,613,612,109,109,109,109,109,109,109,109,
+614,614,614,614,614,614,614,614,614,614,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 156 */
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
/* block 157 */
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+
+/* block 158 */
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 158 */
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,109,109,109,109,109,109,109,109,109,109,109,109,109,
-618,618,618,618,109,109,109,109,109,109,109,109,109,109,109,109,
+616,616,616,109,109,109,109,109,109,109,109,109,109,109,109,109,
+617,617,617,617,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 159 */
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
/* block 160 */
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,109,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -2889,18 +2888,18 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 163 */
+619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+619,619,619,619,619,109,109,109,109,109,109,109,109,109,109,109,
+619,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,109,109,109,109,109,109,109,109,109,109,109,
-620,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,
-621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,
-621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,109,
+620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,109,
/* block 164 */
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,622,
-622,622,622,623,623,623,623,623,623,623,623,623,623,623,623,623,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,621,
+621,621,621,622,622,622,622,622,622,622,622,622,622,622,622,622,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -2935,8 +2934,8 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19,624,395,104,104,104, 19, 19, 19,395,624,624,
-624,624,624, 22, 22, 22, 22, 22, 22, 22, 22,104,104,104,104,104,
+ 19, 19, 19, 19, 19,623,395,104,104,104, 19, 19, 19,395,623,623,
+623,623,623, 22, 22, 22, 22, 22, 22, 22, 22,104,104,104,104,104,
/* block 168 */
104,104,104, 19, 19,104,104,104,104,104,104,104, 19, 19, 19, 19,
@@ -2949,11 +2948,11 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 169 */
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,625,625,625,546,109,109,109,109,109,109,109,109,109,109,
+545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
+545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
+545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
+545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
+545,545,624,624,624,545,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -3105,11 +3104,11 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,626,626,626,626,626,626,626,626,626,626,
-626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,
+109,109,109,109,109,109,625,625,625,625,625,625,625,625,625,625,
+625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,
/* block 185 */
-627, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,109,
+626, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,109,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,109,
@@ -3279,14 +3278,14 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
/* block 202 */
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,109,109,
+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,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,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,109,109,
};
diff --git a/ext/pcre/pcrelib/pcre_valid_utf8.c b/ext/pcre/pcrelib/pcre_valid_utf8.c
index a415927568..3b0f6464a3 100644
--- a/ext/pcre/pcrelib/pcre_valid_utf8.c
+++ b/ext/pcre/pcrelib/pcre_valid_utf8.c
@@ -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-2012 University of Cambridge
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -92,7 +92,7 @@ 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
-PCRE_UTF8_ERR22 Non-character
+PCRE_UTF8_ERR22 Unused (was non-character)
Arguments:
string points to the string
@@ -118,7 +118,6 @@ if (length < 0)
for (p = string; length-- > 0; p++)
{
register pcre_uchar ab, c, d;
- pcre_uint32 v = 0;
c = *p;
if (c < 128) continue; /* ASCII character */
@@ -187,7 +186,6 @@ for (p = string; length-- > 0; p++)
*erroroffset = (int)(p - string) - 2;
return PCRE_UTF8_ERR14;
}
- v = ((c & 0x0f) << 12) | ((d & 0x3f) << 6) | (*p & 0x3f);
break;
/* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2
@@ -215,7 +213,6 @@ for (p = string; length-- > 0; p++)
*erroroffset = (int)(p - string) - 3;
return PCRE_UTF8_ERR13;
}
- v = ((c & 0x07) << 18) | ((d & 0x3f) << 12) | ((p[-1] & 0x3f) << 6) | (*p & 0x3f);
break;
/* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be
@@ -290,14 +287,6 @@ for (p = string; length-- > 0; p++)
*erroroffset = (int)(p - string) - ab;
return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12;
}
-
- /* Reject non-characters. The pointer p is currently at the last byte of the
- character. */
- if ((v & 0xfffeu) == 0xfffeu || (v >= 0xfdd0 && v <= 0xfdef))
- {
- *erroroffset = (int)(p - string) - ab;
- return PCRE_UTF8_ERR22;
- }
}
#else /* Not SUPPORT_UTF */
diff --git a/ext/pcre/pcrelib/pcre_xclass.c b/ext/pcre/pcrelib/pcre_xclass.c
index fa73cd8c9d..ad153be785 100644
--- a/ext/pcre/pcrelib/pcre_xclass.c
+++ b/ext/pcre/pcrelib/pcre_xclass.c
@@ -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-2012 University of Cambridge
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -128,55 +128,120 @@ while ((t = *data++) != XCL_END)
else /* XCL_PROP & XCL_NOTPROP */
{
const ucd_record *prop = GET_UCD(c);
+ BOOL isprop = t == XCL_PROP;
switch(*data)
{
case PT_ANY:
- if (t == XCL_PROP) return !negated;
+ if (isprop) return !negated;
break;
case PT_LAMP:
if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt) == (t == XCL_PROP)) return !negated;
+ prop->chartype == ucp_Lt) == isprop) return !negated;
break;
case PT_GC:
- if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP))
+ if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop)
return !negated;
break;
case PT_PC:
- if ((data[1] == prop->chartype) == (t == XCL_PROP)) return !negated;
+ if ((data[1] == prop->chartype) == isprop) return !negated;
break;
case PT_SC:
- if ((data[1] == prop->script) == (t == XCL_PROP)) return !negated;
+ if ((data[1] == prop->script) == isprop) return !negated;
break;
case PT_ALNUM:
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP))
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop)
return !negated;
break;
- case PT_SPACE: /* Perl space */
- 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;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+ case PT_SPACE: /* Perl space */
case PT_PXSPACE: /* POSIX space */
- 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;
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (isprop) return !negated;
+ break;
+
+ default:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop)
+ return !negated;
+ break;
+ }
break;
case PT_WORD:
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)
- == (t == XCL_PROP))
+ == isprop)
+ return !negated;
+ break;
+
+ case PT_UCNC:
+ if (c < 0xa0)
+ {
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT) == isprop)
+ return !negated;
+ }
+ else
+ {
+ if ((c < 0xd800 || c > 0xdfff) == isprop)
+ return !negated;
+ }
+ break;
+
+ /* The following three properties can occur only in an XCLASS, as there
+ is no \p or \P coding for them. */
+
+ /* Graphic character. Implement this as not Z (space or separator) and
+ not C (other), except for Cf (format) with a few exceptions. This seems
+ to be what Perl does. The exceptional characters are:
+
+ U+061C Arabic Letter Mark
+ U+180E Mongolian Vowel Separator
+ U+2066 - U+2069 Various "isolate"s
+ */
+
+ case PT_PXGRAPH:
+ if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z &&
+ (PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
+ (prop->chartype == ucp_Cf &&
+ c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069))
+ )) == isprop)
+ return !negated;
+ break;
+
+ /* Printable character: same as graphic, with the addition of Zs, i.e.
+ not Zl and not Zp, and U+180E. */
+
+ case PT_PXPRINT:
+ if ((prop->chartype != ucp_Zl &&
+ prop->chartype != ucp_Zp &&
+ (PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
+ (prop->chartype == ucp_Cf &&
+ c != 0x061c && (c < 0x2066 || c > 0x2069))
+ )) == isprop)
+ return !negated;
+ break;
+
+ /* Punctuation: all Unicode punctuation, plus ASCII characters that
+ Unicode treats as symbols rather than punctuation, for Perl
+ compatibility (these are $+<=>^`|~). */
+
+ case PT_PXPUNCT:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P ||
+ (c < 256 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop)
return !negated;
break;
diff --git a/ext/pcre/pcrelib/pcreposix.c b/ext/pcre/pcrelib/pcreposix.c
index 15195c0e98..7cf4a4a657 100644
--- a/ext/pcre/pcrelib/pcreposix.c
+++ b/ext/pcre/pcrelib/pcreposix.c
@@ -110,7 +110,7 @@ static const int eint[] = {
REG_BADPAT, /* POSIX collating elements are not supported */
REG_INVARG, /* this version of PCRE is not compiled with PCRE_UTF8 support */
REG_BADPAT, /* spare error */
- REG_BADPAT, /* character value in \x{...} sequence is too large */
+ REG_BADPAT, /* character value in \x{} or \o{} is too large */
/* 35 */
REG_BADPAT, /* invalid condition (?(0) */
REG_BADPAT, /* \C not allowed in lookbehind assertion */
@@ -162,7 +162,15 @@ static const int eint[] = {
/* 75 */
REG_BADPAT, /* overlong MARK name */
REG_BADPAT, /* character value in \u.... sequence is too large */
- REG_BADPAT /* invalid UTF-32 string (should not occur) */
+ REG_BADPAT, /* invalid UTF-32 string (should not occur) */
+ REG_BADPAT, /* setting UTF is disabled by the application */
+ REG_BADPAT, /* non-hex character in \\x{} (closing brace missing?) */
+ /* 80 */
+ REG_BADPAT, /* non-octal character in \o{} (closing brace missing?) */
+ REG_BADPAT, /* missing opening brace after \o */
+ REG_BADPAT, /* parentheses too deeply nested */
+ REG_BADPAT, /* invalid range in character class */
+ REG_BADPAT /* group name must start with a non-digit */
};
/* Table of texts corresponding to POSIX error codes */
diff --git a/ext/pcre/pcrelib/testdata/grepbinary b/ext/pcre/pcrelib/testdata/grepbinary
new file mode 100644
index 0000000000..5efa130204
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/grepbinary
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/grepfilelist b/ext/pcre/pcrelib/testdata/grepfilelist
new file mode 100644
index 0000000000..dd73ec7f91
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/grepfilelist
@@ -0,0 +1,3 @@
+testdata/grepinputv
+
+testdata/grepinputx
diff --git a/ext/pcre/pcrelib/testdata/grepinput3 b/ext/pcre/pcrelib/testdata/grepinput3
new file mode 100644
index 0000000000..7409cfc07a
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/grepinput3
@@ -0,0 +1,15 @@
+triple: t1_txt s1_tag s_txt p_tag p_txt o_tag o_txt
+
+triple: t2_txt s1_tag s_txt p_tag p_txt o_tag
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+triple: t3_txt s2_tag s_txt p_tag p_txt o_tag o_txt
+
+triple: t4_txt s1_tag s_txt p_tag p_txt o_tag o_txt
+
+triple: t5_txt s1_tag s_txt p_tag p_txt o_tag
+o_txt
+
+triple: t6_txt s2_tag s_txt p_tag p_txt o_tag o_txt
+
+triple: t7_txt s1_tag s_txt p_tag p_txt o_tag o_txt
diff --git a/ext/pcre/pcrelib/testdata/grepinput8 b/ext/pcre/pcrelib/testdata/grepinput8
index 7163aa69d3..c4b8c440f2 100644
--- a/ext/pcre/pcrelib/testdata/grepinput8
+++ b/ext/pcre/pcrelib/testdata/grepinput8
@@ -1,10 +1,10 @@
X one
-X two X three X four X five
+X two X three X four X five
X six
X seven…X eight
X nine
X ten
Before 111
-Before 222
Before 333…Match
+Before 222
Before 333…Match
After 111
After 222
After 333
And so on and so on
diff --git a/ext/pcre/pcrelib/testdata/grepinputv b/ext/pcre/pcrelib/testdata/grepinputv
new file mode 100644
index 0000000000..d33d326b01
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/grepinputv
@@ -0,0 +1,4 @@
+The quick brown
+fox jumps
+over the lazy dog.
+This time it jumps and jumps and jumps.
diff --git a/ext/pcre/pcrelib/testdata/grepoutput b/ext/pcre/pcrelib/testdata/grepoutput
index 733b9d6a3b..9bf9d9d62e 100644
--- a/ext/pcre/pcrelib/testdata/grepoutput
+++ b/ext/pcre/pcrelib/testdata/grepoutput
@@ -705,3 +705,41 @@ RC=0
./testdata/grepinput:zero|a
./testdata/grepinput:.|zero|the|.
RC=0
+---------------------------- Test 102 -----------------------------
+2:
+5:
+7:
+9:
+12:
+14:
+RC=0
+---------------------------- Test 103 -----------------------------
+RC=0
+---------------------------- Test 104 -----------------------------
+2:
+5:
+7:
+9:
+12:
+14:
+RC=0
+---------------------------- Test 105 -----------------------------
+triple: t1_txt s1_tag s_txt p_tag p_txt o_tag o_txt
+
+triple: t2_txt s1_tag s_txt p_tag p_txt o_tag
+Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+triple: t3_txt s2_tag s_txt p_tag p_txt o_tag o_txt
+
+triple: t4_txt s1_tag s_txt p_tag p_txt o_tag o_txt
+
+triple: t5_txt s1_tag s_txt p_tag p_txt o_tag
+o_txt
+
+triple: t6_txt s2_tag s_txt p_tag p_txt o_tag o_txt
+
+triple: t7_txt s1_tag s_txt p_tag p_txt o_tag o_txt
+RC=0
+---------------------------- Test 106 -----------------------------
+a
+RC=0
diff --git a/ext/pcre/pcrelib/testdata/grepoutput8 b/ext/pcre/pcrelib/testdata/grepoutput8
index 385266b3cf..91493bdcf0 100644
--- a/ext/pcre/pcrelib/testdata/grepoutput8
+++ b/ext/pcre/pcrelib/testdata/grepoutput8
@@ -1,12 +1,12 @@
---------------------------- Test U1 ------------------------------
1:X one
-2:X two 3:X three 4:X four 5:X five
+2:X two 3:X three 4:X four 5:X five
6:X six
7:X seven…8:X eight
9:X nine
10:X ten
RC=0
---------------------------- Test U2 ------------------------------
12-Before 111
-13-Before 222
14-Before 333…15:Match
+13-Before 222
14-Before 333…15:Match
16-After 111
17-After 222
18-After 333
RC=0
diff --git a/ext/pcre/pcrelib/testdata/grepoutputN b/ext/pcre/pcrelib/testdata/grepoutputN
index 6760314aa2..1f9f8801e3 100644
--- a/ext/pcre/pcrelib/testdata/grepoutputN
+++ b/ext/pcre/pcrelib/testdata/grepoutputN
@@ -1,16 +1,16 @@
----------------------------- Test N1 ------------------------------
-1:abc 2:def ---------------------------- Test N2 ------------------------------
-1:abc def
+---------------------------- Test N1 ------------------------------
+1:abc 2:def ---------------------------- Test N2 ------------------------------
+1:abc def
2:ghi
-jkl---------------------------- Test N3 ------------------------------
+jkl---------------------------- Test N3 ------------------------------
2:def 3:
ghi
-jkl---------------------------- Test N4 ------------------------------
+jkl---------------------------- Test N4 ------------------------------
2:ghi
-jkl---------------------------- Test N5 ------------------------------
-1:abc 2:def
+jkl---------------------------- Test N5 ------------------------------
+1:abc 2:def
3:ghi
-4:jkl---------------------------- Test N6 ------------------------------
-1:abc 2:def
+4:jkl---------------------------- Test N6 ------------------------------
+1:abc 2:def
3:ghi
4:jkl \ No newline at end of file
diff --git a/ext/pcre/pcrelib/testdata/greppatN4 b/ext/pcre/pcrelib/testdata/greppatN4
new file mode 100644
index 0000000000..7112d84fa1
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/greppatN4
@@ -0,0 +1,2 @@
+xxx
+jkl \ No newline at end of file
diff --git a/ext/pcre/pcrelib/testdata/saved16 b/ext/pcre/pcrelib/testdata/saved16
new file mode 100644
index 0000000000..f86326c9f8
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/saved16
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/saved16BE-1 b/ext/pcre/pcrelib/testdata/saved16BE-1
new file mode 100644
index 0000000000..e6edddc6e0
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/saved16BE-1
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/saved16BE-2 b/ext/pcre/pcrelib/testdata/saved16BE-2
new file mode 100644
index 0000000000..c91ce37bd4
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/saved16BE-2
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/saved16LE-1 b/ext/pcre/pcrelib/testdata/saved16LE-1
new file mode 100644
index 0000000000..5035ec0721
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/saved16LE-1
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/saved16LE-2 b/ext/pcre/pcrelib/testdata/saved16LE-2
new file mode 100644
index 0000000000..656c058d26
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/saved16LE-2
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/saved32 b/ext/pcre/pcrelib/testdata/saved32
new file mode 100644
index 0000000000..a4e27041ce
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/saved32
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/saved32BE-1 b/ext/pcre/pcrelib/testdata/saved32BE-1
new file mode 100644
index 0000000000..b4c2ffe42c
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/saved32BE-1
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/saved32BE-2 b/ext/pcre/pcrelib/testdata/saved32BE-2
new file mode 100644
index 0000000000..79bb5e8805
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/saved32BE-2
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/saved32LE-1 b/ext/pcre/pcrelib/testdata/saved32LE-1
new file mode 100644
index 0000000000..49392b89a1
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/saved32LE-1
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/saved32LE-2 b/ext/pcre/pcrelib/testdata/saved32LE-2
new file mode 100644
index 0000000000..5f64af9b9d
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/saved32LE-2
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/saved8 b/ext/pcre/pcrelib/testdata/saved8
new file mode 100644
index 0000000000..8cf0c1312d
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/saved8
Binary files differ
diff --git a/ext/pcre/pcrelib/testdata/testinput1 b/ext/pcre/pcrelib/testdata/testinput1
index e6d048ad8c..7b36360d04 100644
--- a/ext/pcre/pcrelib/testdata/testinput1
+++ b/ext/pcre/pcrelib/testdata/testinput1
@@ -1,6 +1,8 @@
/-- This set of tests is for features that are compatible with all versions of
- Perl >= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and
- 16-bit PCRE libraries. --/
+ Perl >= 5.10, in non-UTF-8 mode. It should run clean for the 8-bit, 16-bit,
+ and 32-bit PCRE libraries. --/
+
+< forbid 89?=ABCDEFfGILMNPTUWXZ<
/the quick brown fox/
the quick brown fox
@@ -1483,14 +1485,19 @@
abc\100\x30
abc\100\060
abc\100\60
+
+/^A\8B\9C$/
+ A8B9C
+ *** Failers
+ A\08B\09C
+
+/^(A)(B)(C)(D)(E)(F)(G)(H)(I)\8\9$/
+ ABCDEFGHIHI
-/abc\81/
- abc\081
- abc\0\x38\x31
-
-/abc\91/
- abc\091
- abc\0\x39\x31
+/^[A\8B\9C]+$/
+ A8B9C
+ *** Failers
+ A8B9C\x00
/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\12\123/
abcdefghijkllS
@@ -3654,13 +3661,6 @@
/a*/g
abbab
-/^[a-\d]/
- abcde
- -things
- 0digit
- *** Failers
- bcdef
-
/^[\d-a]/
abcde
-things
@@ -3773,9 +3773,9 @@
abc123abc
abc123bc
-/-- This tests for an IPv6 address in the form where it can have up to --/
-/-- eight components, one and only one of which is empty. This must be --/
-/-- an internal component. --/
+/-- This tests for an IPv6 address in the form where it can have up to
+ eight components, one and only one of which is empty. This must be
+ an internal component. --/
/^(?!:) # colon disallowed at start
(?: # start of item
@@ -4221,9 +4221,6 @@
ab
bc
-/^(?=(a)){0}b(?1)/
- backgammon
-
/^(?=(?1))?[az]([abc])d/
abd
zcdxx
@@ -4656,16 +4653,10 @@
/(?<pn> \( ( [^()]++ | (?&pn) )* \) )/x
(ab(cd)ef)
-/^(?!a(*SKIP)b)/
- ac
-
/^(?=a(*SKIP)b|ac)/
** Failers
ac
-/^(?=a(*THEN)b|ac)/
- ac
-
/^(?=a(*PRUNE)b)/
ab
** Failers
@@ -4674,9 +4665,6 @@
/^(?=a(*ACCEPT)b)/
ac
-/^(?(?!a(*SKIP)b))/
- ac
-
/(?>a\Kb)/
ab
@@ -4899,33 +4887,15 @@ however, we need the complication for Perl. ---/
/(A (A|B(*ACCEPT)|C) D)(E)/x
AB
-/\A.*?(?:a|b(*THEN)c)/
- ba
-
-/\A.*?(?:a|bc)/
- ba
-
-/\A.*?(a|b(*THEN)c)/
- ba
-
/\A.*?(a|bc)/
ba
-/\A.*?(?:a|b(*THEN)c)++/
- ba
-
/\A.*?(?:a|bc)++/
ba
-/\A.*?(a|b(*THEN)c)++/
- ba
-
/\A.*?(a|bc)++/
ba
-/\A.*?(?:a|b(*THEN)c|d)/
- ba
-
/\A.*?(?:a|bc|d)/
ba
@@ -5253,9 +5223,6 @@ name were given. ---/
/(a(*COMMIT)b){0}a(?1)|aac/
aac
-/(?!a(*COMMIT)b)ac|cd/
- ac
-
/((?:a?)*)*c/
aac
@@ -5303,4 +5270,400 @@ name were given. ---/
"(?>.*?)foo"
abcdfooxyz
+/(?:(a(*PRUNE)b)){0}(?:(?1)|ac)/
+ ac
+
+/(?:(a(*SKIP)b)){0}(?:(?1)|ac)/
+ ac
+
+/(?<=(*SKIP)ac)a/
+ aa
+
+/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK
+ AAAC
+
+/a(*SKIP:m)x|ac(*:n)(*SKIP:n)d|ac/K
+ acacd
+
+/A(*SKIP:m)x|A(*SKIP:n)x|AB/K
+ AB
+
+/((*SKIP:r)d){0}a(*SKIP:m)x|ac(*:n)|ac/K
+ acacd
+
+/-- Tests that try to figure out how Perl works. My hypothesis is that the
+ first verb that is backtracked onto is the one that acts. This seems to be
+ the case almost all the time, but there is one exception that is perhaps a
+ bug. --/
+
+/-- This matches "aaaac"; each PRUNE advances one character until the subject
+ no longer starts with 5 'a's. --/
+
+/aaaaa(*PRUNE)b|a+c/
+ aaaaaac
+
+/-- Putting SKIP in front of PRUNE makes no difference, as it is never
+backtracked onto, whether or not it has a label. --/
+
+/aaaaa(*SKIP)(*PRUNE)b|a+c/
+ aaaaaac
+
+/aaaaa(*SKIP:N)(*PRUNE)b|a+c/
+ aaaaaac
+
+/aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c/
+ aaaaaac
+
+/-- Putting THEN in front makes no difference. */
+
+/aaaaa(*THEN)(*PRUNE)b|a+c/
+ aaaaaac
+
+/-- However, putting COMMIT in front of the prune changes it to "no match". I
+ think this is inconsistent and possibly a bug. For the moment, running this
+ test is moved out of the Perl-compatible file. --/
+
+/aaaaa(*COMMIT)(*PRUNE)b|a+c/
+
+
+/---- OK, lets play the same game again using SKIP instead of PRUNE. ----/
+
+/-- This matches "ac" because SKIP forces the next match to start on the
+ sixth "a". --/
+
+/aaaaa(*SKIP)b|a+c/
+ aaaaaac
+
+/-- Putting PRUNE in front makes no difference. --/
+
+/aaaaa(*PRUNE)(*SKIP)b|a+c/
+ aaaaaac
+
+/-- Putting THEN in front makes no difference. --/
+
+/aaaaa(*THEN)(*SKIP)b|a+c/
+ aaaaaac
+
+/-- In this case, neither does COMMIT. This still matches "ac". --/
+
+/aaaaa(*COMMIT)(*SKIP)b|a+c/
+ aaaaaac
+
+/-- This gives "no match", as expected. --/
+
+/aaaaa(*COMMIT)b|a+c/
+ aaaaaac
+
+
+/------ Tests using THEN ------/
+
+/-- This matches "aaaaaac", as expected. --/
+
+/aaaaa(*THEN)b|a+c/
+ aaaaaac
+
+/-- Putting SKIP in front makes no difference. --/
+
+/aaaaa(*SKIP)(*THEN)b|a+c/
+ aaaaaac
+
+/-- Putting PRUNE in front makes no difference. --/
+
+/aaaaa(*PRUNE)(*THEN)b|a+c/
+ aaaaaac
+
+/-- Putting COMMIT in front makes no difference. --/
+
+/aaaaa(*COMMIT)(*THEN)b|a+c/
+ aaaaaac
+
+/-- End of "priority" tests --/
+
+/aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+/
+ aaaaaa
+
+/aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+/
+ aaaaaa
+
+/aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+/
+ aaaaaa
+
+/aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+/
+ aaaaaa
+
+/a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c/
+ aaaac
+
+/a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c/
+ aaaac
+
+/aaa(*PRUNE:A)a(*SKIP:A)b|a+c/
+ aaaac
+
+/aaa(*MARK:A)a(*SKIP:A)b|a+c/
+ aaaac
+
+/a(*:m)a(*COMMIT)(*SKIP:m)b|a+c/K
+ aaaaaac
+
+/.?(a|b(*THEN)c)/
+ ba
+
+/(a(*COMMIT)b)c|abd/
+ abc
+ abd
+
+/(?=a(*COMMIT)b)abc|abd/
+ abc
+ abd
+
+/(?>a(*COMMIT)b)c|abd/
+ abc
+ abd
+
+/a(?=b(*COMMIT)c)[^d]|abd/
+ abd
+ abc
+
+/a(?=bc).|abd/
+ abd
+ abc
+
+/a(?>b(*COMMIT)c)d|abd/
+ abceabd
+
+/a(?>bc)d|abd/
+ abceabd
+
+/(?>a(*COMMIT)b)c|abd/
+ abd
+
+/(?>a(*COMMIT)c)d|abd/
+ abd
+
+/((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/
+ ac
+
+/-- These tests were formerly in test 2, but changes in PCRE and Perl have
+ made them compatible. --/
+
+/^(a)?(?(1)a|b)+$/
+ *** Failers
+ a
+
+/(?=a\Kb)ab/
+ ab
+
+/(?!a\Kb)ac/
+ ac
+
+/^abc(?<=b\Kc)d/
+ abcd
+
+/^abc(?<!b\Kq)d/
+ abcd
+
+
+/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK
+ AAAC
+
+/^((abc|abcx)(*THEN)y|abcd)/
+ abcd
+ *** Failers
+ abcxy
+
+/^((yes|no)(*THEN)(*F))?/
+ yes
+
+/(A (.*) C? (*THEN) | A D) (*FAIL)/x
+AbcdCBefgBhiBqz
+
+/(A (.*) C? (*THEN) | A D) z/x
+AbcdCBefgBhiBqz
+
+/(A (.*) C? (*THEN) | A D) \s* (*FAIL)/x
+AbcdCBefgBhiBqz
+
+/(A (.*) C? (*THEN) | A D) \s* z/x
+AbcdCBefgBhiBqz
+
+/(A (.*) (?:C|) (*THEN) | A D) (*FAIL)/x
+AbcdCBefgBhiBqz
+
+/(A (.*) (?:C|) (*THEN) | A D) z/x
+AbcdCBefgBhiBqz
+
+/(A (.*) C{0,6} (*THEN) | A D) (*FAIL)/x
+AbcdCBefgBhiBqz
+
+/(A (.*) C{0,6} (*THEN) | A D) z/x
+AbcdCBefgBhiBqz
+
+/(A (.*) (CE){0,6} (*THEN) | A D) (*FAIL)/x
+AbcdCEBefgBhiBqz
+
+/(A (.*) (CE){0,6} (*THEN) | A D) z/x
+AbcdCEBefgBhiBqz
+
+/(A (.*) (CE*){0,6} (*THEN) | A D) (*FAIL)/x
+AbcdCBefgBhiBqz
+
+/(A (.*) (CE*){0,6} (*THEN) | A D) z/x
+AbcdCBefgBhiBqz
+
+/(?=a(*COMMIT)b|ac)ac|ac/
+ ac
+
+/(?=a(*COMMIT)b|(ac)) ac | (a)c/x
+ ac
+
+/--------/
+
+/(?(?!b(*THEN)a)bn|bnn)/
+ bnn
+
+/(?!b(*SKIP)a)bn|bnn/
+ bnn
+
+/(?(?!b(*SKIP)a)bn|bnn)/
+ bnn
+
+/(?!b(*PRUNE)a)bn|bnn/
+ bnn
+
+/(?(?!b(*PRUNE)a)bn|bnn)/
+ bnn
+
+/(?!b(*COMMIT)a)bn|bnn/
+ bnn
+
+/(?(?!b(*COMMIT)a)bn|bnn)/
+ bnn
+
+/(?=b(*SKIP)a)bn|bnn/
+ bnn
+
+/(?=b(*THEN)a)bn|bnn/
+ bnn
+
+ /^(?!a(*SKIP)b)/
+ ac
+
+ /^(?!a(*SKIP)b)../
+ acd
+
+/(?!a(*SKIP)b)../
+ acd
+
+/^(?(?!a(*SKIP)b))/
+ ac
+
+/^(?!a(*PRUNE)b)../
+ acd
+
+/(?!a(*PRUNE)b)../
+ acd
+
+ /(?!a(*COMMIT)b)ac|cd/
+ ac
+
+/\A.*?(?:a|bc)/
+ ba
+
+/^(A(*THEN)B|C(*THEN)D)/
+ CD
+
+/(*:m(m)(?&y)(?(DEFINE)(?<y>b))/K
+ abc
+
+/(*PRUNE:m(m)(?&y)(?(DEFINE)(?<y>b))/K
+ abc
+
+/(*SKIP:m(m)(?&y)(?(DEFINE)(?<y>b))/K
+ abc
+
+/(*THEN:m(m)(?&y)(?(DEFINE)(?<y>b))/K
+ abc
+
+/^\d*\w{4}/
+ 1234
+ 123
+
+/^[^b]*\w{4}/
+ aaaa
+ aaa
+
+/^[^b]*\w{4}/i
+ aaaa
+ aaa
+
+/^a*\w{4}/
+ aaaa
+ aaa
+
+/^a*\w{4}/i
+ aaaa
+ aaa
+
+/(?(?=ab)ab)/+
+ ca
+ cd
+
+/(?:(?<n>foo)|(?<n>bar))\k<n>/J
+ foofoo
+ barbar
+
+/(?<n>A)(?:(?<n>foo)|(?<n>bar))\k<n>/J
+ AfooA
+ AbarA
+ ** Failers
+ Afoofoo
+ Abarbar
+
+/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/
+ 1 IN SOA non-sp1 non-sp2(
+
+/^ (?:(?<A>A)|(?'B'B)(?<A>A)) (?('A')x) (?(<B>)y)$/xJ
+ Ax
+ BAxy
+
+/^A\xZ/
+ A\0Z
+
+/^A\o{123}B/
+ A\123B
+
+/ ^ a + + b $ /x
+ aaaab
+
+/ ^ a + #comment
+ + b $ /x
+ aaaab
+
+/ ^ a + #comment
+ #comment
+ + b $ /x
+ aaaab
+
+/ ^ (?> a + ) b $ /x
+ aaaab
+
+/ ^ ( a + ) + + \w $ /x
+ aaaab
+
+/(?:a\Kb)*+/+
+ ababc
+
+/(?>a\Kb)*/+
+ ababc
+
+/(?:a\Kb)*/+
+ ababc
+
+/(a\Kb)*+/+
+ ababc
+
+/(a\Kb)*/+
+ ababc
+
/-- End of testinput1 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput10 b/ext/pcre/pcrelib/testdata/testinput10
index f20dcb3d18..93ddb3a75b 100644
--- a/ext/pcre/pcrelib/testdata/testinput10
+++ b/ext/pcre/pcrelib/testdata/testinput10
@@ -139,6 +139,12 @@
/^\p{Cf}/8
\x{601}
+ \x{180e}
+ \x{061c}
+ \x{2066}
+ \x{2067}
+ \x{2068}
+ \x{2069}
** Failers
\x{09f}
@@ -199,11 +205,12 @@
/^\p{Mn}/8
\x{300}
+ \x{1a1b}
** Failers
X
\x{903}
-/^\p{Nd}+/8
+/^\p{Nd}+/8O
0123456789\x{660}\x{661}\x{662}\x{663}\x{664}\x{665}\x{666}\x{667}\x{668}\x{669}\x{66a}
\x{6f0}\x{6f1}\x{6f2}\x{6f3}\x{6f4}\x{6f5}\x{6f6}\x{6f7}\x{6f8}\x{6f9}\x{6fa}
\x{966}\x{967}\x{968}\x{969}\x{96a}\x{96b}\x{96c}\x{96d}\x{96e}\x{96f}\x{970}
@@ -243,6 +250,8 @@
]
}
\x{f3b}
+ \x{2309}
+ \x{230b}
** Failers
X
\x{203f}
@@ -250,7 +259,7 @@
[
{
\x{f3c}
-
+
/^\p{Pf}/8
\x{bb}
\x{2019}
@@ -277,6 +286,8 @@
[
{
\x{f3c}
+ \x{2308}
+ \x{230a}
** Failers
X
)
@@ -326,7 +337,6 @@
\ \
\x{a0}
\x{1680}
- \x{180e}
\x{2000}
\x{2001}
** Failers
@@ -423,23 +433,23 @@
** Failers
1234
-/\D+/8
+/\D+/8O
11111111111111111111111111111111111111111111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-/\P{Nd}+/8
+/\P{Nd}+/8O
11111111111111111111111111111111111111111111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-/[\D]+/8
+/[\D]+/8O
11111111111111111111111111111111111111111111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-/[\P{Nd}]+/8
+/[\P{Nd}]+/8O
11111111111111111111111111111111111111111111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-/[\D\P{Nd}]+/8
+/[\D\P{Nd}]+/8O
11111111111111111111111111111111111111111111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -886,19 +896,19 @@
** Failers
\x{0b}
-/^>\p{Xsp}+/8
+/^>\p{Xsp}+/8O
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
-/^>\p{Xsp}*/8
+/^>\p{Xsp}*/8O
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
-/^>\p{Xsp}{2,9}/8
+/^>\p{Xsp}{2,9}/8O
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
-/^>[\p{Xsp}]/8
+/^>[\p{Xsp}]/8O
>\x{2028}\x{0b}
-/^>[\p{Xsp}]+/8
+/^>[\p{Xsp}]+/8O
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
/^>\p{Xps}/8
@@ -1334,4 +1344,76 @@
/is{2}t/8i
iskt
+/^\p{Xuc}/8
+ $abc
+ @abc
+ `abc
+ \x{1234}abc
+ ** Failers
+ abc
+
+/^\p{Xuc}+/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\p{Xuc}+?/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\p{Xuc}+?\*/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\p{Xuc}++/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\p{Xuc}{3,5}/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\p{Xuc}{3,5}?/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^[\p{Xuc}]/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^[\p{Xuc}]+/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\P{Xuc}/8
+ abc
+ ** Failers
+ $abc
+ @abc
+ `abc
+ \x{1234}abc
+
+/^[\P{Xuc}]/8
+ abc
+ ** Failers
+ $abc
+ @abc
+ `abc
+ \x{1234}abc
+
+/^A\s+Z/8W
+ A\x{2005}Z
+ A\x{85}\x{180e}\x{2005}Z
+
+/^A[\s]+Z/8W
+ A\x{2005}Z
+ A\x{85}\x{180e}\x{2005}Z
+
/-- End of testinput10 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput11 b/ext/pcre/pcrelib/testdata/testinput11
new file mode 100644
index 0000000000..391ada7aa8
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput11
@@ -0,0 +1,135 @@
+/-- These are a few representative patterns whose lengths and offsets are to be
+shown when the link size is 2. This is just a doublecheck test to ensure the
+sizes don't go horribly wrong when something is changed. The pattern contents
+are all themselves checked in other tests. Unicode, including property support,
+is required for these tests. --/
+
+/((?i)b)/BM
+
+/(?s)(.*X|^B)/BM
+
+/(?s:.*X|^B)/BM
+
+/^[[:alnum:]]/BM
+
+/#/IxMD
+
+/a#/IxMD
+
+/x?+/BM
+
+/x++/BM
+
+/x{1,3}+/BM
+
+/(x)*+/BM
+
+/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM
+
+|8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM
+
+|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM
+
+/(a(?1)b)/BM
+
+/(a(?1)+b)/BM
+
+/a(?P<name1>b|c)d(?P<longername2>e)/BM
+
+/(?:a(?P<c>c(?P<d>d)))(?P<a>a)/BM
+
+/(?P<a>a)...(?P=a)bbb(?P>a)d/BM
+
+/abc(?C255)de(?C)f/BM
+
+/abcde/CBM
+
+/\x{100}/8BM
+
+/\x{1000}/8BM
+
+/\x{10000}/8BM
+
+/\x{100000}/8BM
+
+/\x{10ffff}/8BM
+
+/\x{110000}/8BM
+
+/[\x{ff}]/8BM
+
+/[\x{100}]/8BM
+
+/\x80/8BM
+
+/\xff/8BM
+
+/\x{0041}\x{2262}\x{0391}\x{002e}/D8M
+
+/\x{D55c}\x{ad6d}\x{C5B4}/D8M
+
+/\x{65e5}\x{672c}\x{8a9e}/D8M
+
+/[\x{100}]/8BM
+
+/[Z\x{100}]/8BM
+
+/^[\x{100}\E-\Q\E\x{150}]/B8M
+
+/^[\QĀ\E-\QŐ\E]/B8M
+
+/^[\QĀ\E-\QŐ\E/B8M
+
+/[\p{L}]/BM
+
+/[\p{^L}]/BM
+
+/[\P{L}]/BM
+
+/[\P{^L}]/BM
+
+/[abc\p{L}\x{0660}]/8BM
+
+/[\p{Nd}]/8BM
+
+/[\p{Nd}+-]+/8BM
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM
+
+/[\x{105}-\x{109}]/8iBM
+
+/( ( (?(1)0|) )* )/xBM
+
+/( (?(1)0|)* )/xBM
+
+/[a]/BM
+
+/[a]/8BM
+
+/[\xaa]/BM
+
+/[\xaa]/8BM
+
+/[^a]/BM
+
+/[^a]/8BM
+
+/[^\xaa]/BM
+
+/[^\xaa]/8BM
+
+/[^\d]/8WB
+
+/[[:^alpha:][:^cntrl:]]+/8WB
+
+/[[:^cntrl:][:^alpha:]]+/8WB
+
+/[[:alpha:]]+/8WB
+
+/[[:^alpha:]\S]+/8WB
+
+/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B
+
+/-- End of testinput11 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput12 b/ext/pcre/pcrelib/testdata/testinput12
new file mode 100644
index 0000000000..5d727af26a
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput12
@@ -0,0 +1,90 @@
+/-- This test is run only when JIT support is available. It checks for a
+successful and an unsuccessful JIT compile and save and restore behaviour,
+and a couple of things that are different with JIT. --/
+
+/abc/S+I
+
+/(?(?C1)(?=a)a)/S+I
+
+/(?(?C1)(?=a)a)/S!+I
+
+/abc/S+I>testsavedregex
+
+<testsavedregex
+ abc
+
+/a*/SI
+
+/(?(R)a*(?1)|((?R))b)/S+
+ aaaabcde
+
+/-- Test various compile modes --/
+
+/abcd/S++
+ abcd
+ xyz
+
+/abcd/S+
+ abcd
+ ab\P
+ ab\P\P
+ xyz
+
+/abcd/S++
+ abcd
+ ab\P
+ ab\P\P
+ xyz
+
+/abcd/S++1
+ abcd
+ ab\P
+ ab\P\P
+ xyz
+ xyz\P
+
+/abcd/S++2
+ abcd
+ ab\P
+ ab\P\P
+ xyz
+
+/abcd/S++3
+ abcd
+ ab\P
+ ab\P\P
+ xyz
+
+/abcd/S++4
+ abcd
+ ab\P
+ ab\P\P
+ xyz
+
+/abcd/S++5
+ abcd
+ ab\P
+ ab\P\P
+ xyz
+
+/abcd/S++6
+ abcd
+ ab\P
+ ab\P\P
+ xyz
+
+/abcd/S++7
+ abcd
+ ab\P
+ ab\P\P
+ xyz
+
+/abcd/S++2I
+
+/(*NO_START_OPT)a(*:m)b/KS++
+ a
+
+/^12345678abcd/mS++
+ 12345678abcd
+
+/-- End of testinput12 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput13 b/ext/pcre/pcrelib/testdata/testinput13
new file mode 100644
index 0000000000..c7bc67bb17
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput13
@@ -0,0 +1,9 @@
+/-- This test is run only when JIT support is not available. It checks that an
+attempt to use it has the expected behaviour. It also tests things that
+are different without JIT. --/
+
+/abc/S+I
+
+/a*/SI
+
+/-- End of testinput13 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput14 b/ext/pcre/pcrelib/testdata/testinput14
new file mode 100644
index 0000000000..325ed9e361
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput14
@@ -0,0 +1,343 @@
+/-- This set of tests is run only with the 8-bit library. They do not require
+ UTF-8 or Unicode property support. The file starts with all the tests of
+ the POSIX interface, because that is supported only with the 8-bit library.
+ --/
+
+< forbid 8W
+
+/abc/P
+ abc
+ *** Failers
+
+/^abc|def/P
+ abcdef
+ abcdef\B
+
+/.*((abc)$|(def))/P
+ defabc
+ \Zdefabc
+
+/the quick brown fox/P
+ the quick brown fox
+ *** Failers
+ The Quick Brown Fox
+
+/the quick brown fox/Pi
+ the quick brown fox
+ The Quick Brown Fox
+
+/abc.def/P
+ *** Failers
+ abc\ndef
+
+/abc$/P
+ abc
+ abc\n
+
+/(abc)\2/P
+
+/(abc\1)/P
+ abc
+
+/a*(b+)(z)(z)/P
+ aaaabbbbzzzz
+ aaaabbbbzzzz\O0
+ aaaabbbbzzzz\O1
+ aaaabbbbzzzz\O2
+ aaaabbbbzzzz\O3
+ aaaabbbbzzzz\O4
+ aaaabbbbzzzz\O5
+
+/ab.cd/P
+ ab-cd
+ ab=cd
+ ** Failers
+ ab\ncd
+
+/ab.cd/Ps
+ ab-cd
+ ab=cd
+ ab\ncd
+
+/a(b)c/PN
+ abc
+
+/a(?P<name>b)c/PN
+ abc
+
+/a?|b?/P
+ abc
+ ** Failers
+ ddd\N
+
+/\w+A/P
+ CDAAAAB
+
+/\w+A/PU
+ CDAAAAB
+
+/\Biss\B/I+P
+ Mississippi
+
+/abc/\P
+
+/-- End of POSIX tests --/
+
+/a\Cb/
+ aXb
+ a\nb
+ ** Failers (too big char)
+ A\x{123}B
+ A\o{443}B
+
+/\x{100}/I
+
+/\o{400}/I
+
+/ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional leading comment
+(?: (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address
+| # or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # one word, optionally followed by....
+(?:
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or...
+\(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) | # comments, or...
+
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+# quoted strings
+)*
+< (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # leading <
+(?: @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* , (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+)* # further okay, if led by comma
+: # closing colon
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* )? # optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address spec
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* > # trailing >
+# name and address
+) (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional trailing comment
+/xSI
+
+/-- Although this saved pattern was compiled with link-size=2, it does no harm
+to run this test with other link sizes because it is going to generated a
+"compiled in wrong mode" error as soon as it is loaded, so the link size does
+not matter. --/
+
+<!testsaved16
+
+<!testsaved32
+
+/\h/SI
+
+/\H/SI
+
+/\v/SI
+
+/\V/SI
+
+/\R/SI
+
+/[\h]/BZ
+ >\x09<
+
+/[\h]+/BZ
+ >\x09\x20\xa0<
+
+/[\v]/BZ
+
+/[\H]/BZ
+
+/[^\h]/BZ
+
+/[\V]/BZ
+
+/[\x0a\V]/BZ
+
+/\777/I
+
+/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K
+ XX
+
+/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K
+ XX
+
+/\u0100/<JS>
+
+/[\u0100-\u0200]/<JS>
+
+/[^\x00-a]{12,}[^b-\xff]*/BZ
+
+/[^\s]*\s* [^\W]+\W+ [^\d]*?\d0 [^\d\w]{4,6}?\w*A/BZ
+
+/-- End of testinput14 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput15 b/ext/pcre/pcrelib/testdata/testinput15
new file mode 100644
index 0000000000..83e2677347
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput15
@@ -0,0 +1,366 @@
+/-- This set of tests is for UTF-8 support but not Unicode property support,
+ and is relevant only to the 8-bit library. --/
+
+< forbid W
+
+/X(\C{3})/8
+ X\x{1234}
+
+/X(\C{4})/8
+ X\x{1234}YZ
+
+/X\C*/8
+ XYZabcdce
+
+/X\C*?/8
+ XYZabcde
+
+/X\C{3,5}/8
+ Xabcdefg
+ X\x{1234}
+ X\x{1234}YZ
+ X\x{1234}\x{512}
+ X\x{1234}\x{512}YZ
+
+/X\C{3,5}?/8
+ Xabcdefg
+ X\x{1234}
+ X\x{1234}YZ
+ X\x{1234}\x{512}
+
+/a\Cb/8
+ aXb
+ a\nb
+
+/a\C\Cb/8
+ a\x{100}b
+
+/ab\Cde/8
+ abXde
+
+/a\C\Cb/8
+ a\x{100}b
+ ** Failers
+ a\x{12257}b
+
+/[]/8
+
+//8
+
+/xxx/8
+
+/xxx/8?DZSSO
+
+/badutf/8
+ \xdf
+ \xef
+ \xef\x80
+ \xf7
+ \xf7\x80
+ \xf7\x80\x80
+ \xfb
+ \xfb\x80
+ \xfb\x80\x80
+ \xfb\x80\x80\x80
+ \xfd
+ \xfd\x80
+ \xfd\x80\x80
+ \xfd\x80\x80\x80
+ \xfd\x80\x80\x80\x80
+ \xdf\x7f
+ \xef\x7f\x80
+ \xef\x80\x7f
+ \xf7\x7f\x80\x80
+ \xf7\x80\x7f\x80
+ \xf7\x80\x80\x7f
+ \xfb\x7f\x80\x80\x80
+ \xfb\x80\x7f\x80\x80
+ \xfb\x80\x80\x7f\x80
+ \xfb\x80\x80\x80\x7f
+ \xfd\x7f\x80\x80\x80\x80
+ \xfd\x80\x7f\x80\x80\x80
+ \xfd\x80\x80\x7f\x80\x80
+ \xfd\x80\x80\x80\x7f\x80
+ \xfd\x80\x80\x80\x80\x7f
+ \xed\xa0\x80
+ \xc0\x8f
+ \xe0\x80\x8f
+ \xf0\x80\x80\x8f
+ \xf8\x80\x80\x80\x8f
+ \xfc\x80\x80\x80\x80\x8f
+ \x80
+ \xfe
+ \xff
+
+/badutf/8
+ \xfb\x80\x80\x80\x80
+ \xfd\x80\x80\x80\x80\x80
+ \xf7\xbf\xbf\xbf
+
+/shortutf/8
+ \P\P\xdf
+ \P\P\xef
+ \P\P\xef\x80
+ \P\P\xf7
+ \P\P\xf7\x80
+ \P\P\xf7\x80\x80
+ \P\P\xfb
+ \P\P\xfb\x80
+ \P\P\xfb\x80\x80
+ \P\P\xfb\x80\x80\x80
+ \P\P\xfd
+ \P\P\xfd\x80
+ \P\P\xfd\x80\x80
+ \P\P\xfd\x80\x80\x80
+ \P\P\xfd\x80\x80\x80\x80
+
+/anything/8
+ \xc0\x80
+ \xc1\x8f
+ \xe0\x9f\x80
+ \xf0\x8f\x80\x80
+ \xf8\x87\x80\x80\x80
+ \xfc\x83\x80\x80\x80\x80
+ \xfe\x80\x80\x80\x80\x80
+ \xff\x80\x80\x80\x80\x80
+ \xc3\x8f
+ \xe0\xaf\x80
+ \xe1\x80\x80
+ \xf0\x9f\x80\x80
+ \xf1\x8f\x80\x80
+ \xf8\x88\x80\x80\x80
+ \xf9\x87\x80\x80\x80
+ \xfc\x84\x80\x80\x80\x80
+ \xfd\x83\x80\x80\x80\x80
+ \?\xf8\x88\x80\x80\x80
+ \?\xf9\x87\x80\x80\x80
+ \?\xfc\x84\x80\x80\x80\x80
+ \?\xfd\x83\x80\x80\x80\x80
+
+/\x{100}/8DZ
+
+/\x{1000}/8DZ
+
+/\x{10000}/8DZ
+
+/\x{100000}/8DZ
+
+/\x{10ffff}/8DZ
+
+/[\x{ff}]/8DZ
+
+/[\x{100}]/8DZ
+
+/\x80/8DZ
+
+/\xff/8DZ
+
+/\x{D55c}\x{ad6d}\x{C5B4}/DZ8
+ \x{D55c}\x{ad6d}\x{C5B4}
+
+/\x{65e5}\x{672c}\x{8a9e}/DZ8
+ \x{65e5}\x{672c}\x{8a9e}
+
+/\x{80}/DZ8
+
+/\x{084}/DZ8
+
+/\x{104}/DZ8
+
+/\x{861}/DZ8
+
+/\x{212ab}/DZ8
+
+/-- This one is here not because it's different to Perl, but because the way
+the captured single-byte is displayed. (In Perl it becomes a character, and you
+can't tell the difference.) --/
+
+/X(\C)(.*)/8
+ X\x{1234}
+ X\nabc
+
+/-- This one is here because Perl gives out a grumbly error message (quite
+correctly, but that messes up comparisons). --/
+
+/a\Cb/8
+ *** Failers
+ a\x{100}b
+
+/[^ab\xC0-\xF0]/8SDZ
+ \x{f1}
+ \x{bf}
+ \x{100}
+ \x{1000}
+ *** Failers
+ \x{c0}
+ \x{f0}
+
+/Ā{3,4}/8SDZ
+ \x{100}\x{100}\x{100}\x{100\x{100}
+
+/(\x{100}+|x)/8SDZ
+
+/(\x{100}*a|x)/8SDZ
+
+/(\x{100}{0,2}a|x)/8SDZ
+
+/(\x{100}{1,2}a|x)/8SDZ
+
+/\x{100}/8DZ
+
+/a\x{100}\x{101}*/8DZ
+
+/a\x{100}\x{101}+/8DZ
+
+/[^\x{c4}]/DZ
+
+/[\x{100}]/8DZ
+ \x{100}
+ Z\x{100}
+ \x{100}Z
+ *** Failers
+
+/[\xff]/DZ8
+ >\x{ff}<
+
+/[^\xff]/8DZ
+
+/\x{100}abc(xyz(?1))/8DZ
+
+/a\x{1234}b/P8
+ a\x{1234}b
+
+/\777/8I
+ \x{1ff}
+ \777
+
+/\x{100}+\x{200}/8DZ
+
+/\x{100}+X/8DZ
+
+/^[\QĀ\E-\QŐ\E/BZ8
+
+/-- This tests the stricter UTF-8 check according to RFC 3629. --/
+
+/X/8
+ \x{d800}
+ \x{d800}\?
+ \x{da00}
+ \x{da00}\?
+ \x{dfff}
+ \x{dfff}\?
+ \x{110000}
+ \x{110000}\?
+ \x{2000000}
+ \x{2000000}\?
+ \x{7fffffff}
+ \x{7fffffff}\?
+
+/(*UTF8)\x{1234}/
+ abcd\x{1234}pqr
+
+/(*CRLF)(*UTF)(*BSR_UNICODE)a\Rb/I
+
+/\h/SI8
+ ABC\x{09}
+ ABC\x{20}
+ ABC\x{a0}
+ ABC\x{1680}
+ ABC\x{180e}
+ ABC\x{2000}
+ ABC\x{202f}
+ ABC\x{205f}
+ ABC\x{3000}
+
+/\v/SI8
+ ABC\x{0a}
+ ABC\x{0b}
+ ABC\x{0c}
+ ABC\x{0d}
+ ABC\x{85}
+ ABC\x{2028}
+
+/\h*A/SI8
+ CDBABC
+
+/\v+A/SI8
+
+/\s?xxx\s/8SI
+
+/\sxxx\s/I8ST1
+ AB\x{85}xxx\x{a0}XYZ
+ AB\x{a0}xxx\x{85}XYZ
+
+/\S \S/I8ST1
+ \x{a2} \x{84}
+ A Z
+
+/a+/8
+ a\x{123}aa\>1
+ a\x{123}aa\>2
+ a\x{123}aa\>3
+ a\x{123}aa\>4
+ a\x{123}aa\>5
+ a\x{123}aa\>6
+
+/\x{1234}+/iS8I
+
+/\x{1234}+?/iS8I
+
+/\x{1234}++/iS8I
+
+/\x{1234}{2}/iS8I
+
+/[^\x{c4}]/8DZ
+
+/X+\x{200}/8DZ
+
+/\R/SI8
+
+/\777/8DZ
+
+/\w+\x{C4}/8BZ
+ a\x{C4}\x{C4}
+
+/\w+\x{C4}/8BZT1
+ a\x{C4}\x{C4}
+
+/\W+\x{C4}/8BZ
+ !\x{C4}
+
+/\W+\x{C4}/8BZT1
+ !\x{C4}
+
+/\W+\x{A1}/8BZ
+ !\x{A1}
+
+/\W+\x{A1}/8BZT1
+ !\x{A1}
+
+/X\s+\x{A0}/8BZ
+ X\x20\x{A0}\x{A0}
+
+/X\s+\x{A0}/8BZT1
+ X\x20\x{A0}\x{A0}
+
+/\S+\x{A0}/8BZ
+ X\x{A0}\x{A0}
+
+/\S+\x{A0}/8BZT1
+ X\x{A0}\x{A0}
+
+/\x{a0}+\s!/8BZ
+ \x{a0}\x20!
+
+/\x{a0}+\s!/8BZT1
+ \x{a0}\x20!
+
+/A/8
+ \x{ff000041}
+ \x{7f000041}
+
+/(*UTF8)abc/9
+
+/abc/89
+
+/-- End of testinput15 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput16 b/ext/pcre/pcrelib/testdata/testinput16
new file mode 100644
index 0000000000..e7a05ae0d4
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput16
@@ -0,0 +1,35 @@
+/-- This set of tests is run only with the 8-bit library when Unicode property
+ support is available. It starts with tests of the POSIX interface, because
+ that is supported only with the 8-bit library. --/
+
+/\w/P
+ +++\x{c2}
+
+/\w/WP
+ +++\x{c2}
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ
+
+/AB\x{1fb0}/8DZ
+
+/AB\x{1fb0}/8DZi
+
+/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI
+ \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}
+ \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f}
+
+/[ⱥ]/8iBZ
+
+/[^ⱥ]/8iBZ
+
+/\h/SI
+
+/\v/SI
+
+/\R/SI
+
+/[[:blank:]]/WBZ
+
+/-- End of testinput16 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput17 b/ext/pcre/pcrelib/testdata/testinput17
new file mode 100644
index 0000000000..1d933c7942
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput17
@@ -0,0 +1,307 @@
+/-- This set of tests is for the 16- and 32-bit library's basic (non-UTF-16
+ or -32) features that are not compatible with the 8-bit library, or which
+ give different output in 16- or 32-bit mode. --/
+
+< forbid 8W
+
+/a\Cb/
+ aXb
+ a\nb
+
+/[^\x{c4}]/DZ
+
+/\x{100}/I
+
+/ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional leading comment
+(?: (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address
+| # or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # one word, optionally followed by....
+(?:
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or...
+\(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) | # comments, or...
+
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+# quoted strings
+)*
+< (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # leading <
+(?: @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* , (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+)* # further okay, if led by comma
+: # closing colon
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* )? # optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address spec
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* > # trailing >
+# name and address
+) (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional trailing comment
+/xSI
+
+/[\h]/BZ
+ >\x09<
+
+/[\h]+/BZ
+ >\x09\x20\xa0<
+
+/[\v]/BZ
+
+/[^\h]/BZ
+
+/\h+/SI
+ \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000}
+ \x{3001}\x{2fff}\x{200a}\xa0\x{2000}
+
+/[\h\x{dc00}]+/BZSI
+ \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000}
+ \x{3001}\x{2fff}\x{200a}\xa0\x{2000}
+
+/\H+/SI
+ \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f}
+ \x{2000}\x{200a}\x{1fff}\x{200b}
+ \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060}
+ \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001}
+
+/[\H\x{d800}]+/
+ \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f}
+ \x{2000}\x{200a}\x{1fff}\x{200b}
+ \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060}
+ \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001}
+
+/\v+/SI
+ \x{2027}\x{2030}\x{2028}\x{2029}
+ \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d
+
+/[\v\x{dc00}]+/BZSI
+ \x{2027}\x{2030}\x{2028}\x{2029}
+ \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d
+
+/\V+/SI
+ \x{2028}\x{2029}\x{2027}\x{2030}
+ \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86
+
+/[\V\x{d800}]+/
+ \x{2028}\x{2029}\x{2027}\x{2030}
+ \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86
+
+/\R+/SI<bsr_unicode>
+ \x{2027}\x{2030}\x{2028}\x{2029}
+ \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d
+
+/\x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00}/I
+ \x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00}
+
+/[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZ
+
+/[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZi
+
+/[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZ
+
+/[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZi
+
+/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K
+ XX
+
+/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K
+ XX
+
+/\u0100/<JS>BZ
+
+/[\u0100-\u0200]/<JS>BZ
+
+/\ud800/<JS>BZ
+
+/^\x{ffff}+/i
+ \x{ffff}
+
+/^\x{ffff}?/i
+ \x{ffff}
+
+/^\x{ffff}*/i
+ \x{ffff}
+
+/^\x{ffff}{3}/i
+ \x{ffff}\x{ffff}\x{ffff}
+
+/^\x{ffff}{0,3}/i
+ \x{ffff}
+
+/[^\x00-a]{12,}[^b-\xff]*/BZ
+
+/[^\s]*\s* [^\W]+\W+ [^\d]*?\d0 [^\d\w]{4,6}?\w*A/BZ
+
+/a*[b-\x{200}]?a#a*[b-\x{200}]?b#[a-f]*[g-\x{200}]*#[g-\x{200}]*[a-c]*#[g-\x{200}]*[a-h]*/BZ
+
+/^[\x{1234}\x{4321}]{2,4}?/
+ \x{1234}\x{1234}\x{1234}
+
+/-- End of testinput17 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput18 b/ext/pcre/pcrelib/testdata/testinput18
new file mode 100644
index 0000000000..abff34e73a
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput18
@@ -0,0 +1,300 @@
+/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to
+ the 16- and 32-bit libraries. --/
+
+< forbid W
+
+/xxx/8?DZSS
+
+/abc/8
+ ]
+
+/X(\C{3})/8
+ X\x{11234}Y
+ X\x{11234}YZ
+
+/X(\C{4})/8
+ X\x{11234}YZ
+ X\x{11234}YZW
+
+/X\C*/8
+ XYZabcdce
+
+/X\C*?/8
+ XYZabcde
+
+/X\C{3,5}/8
+ Xabcdefg
+ X\x{11234}Y
+ X\x{11234}YZ
+ X\x{11234}\x{512}
+ X\x{11234}\x{512}YZ
+ X\x{11234}\x{512}\x{11234}Z
+
+/X\C{3,5}?/8
+ Xabcdefg
+ X\x{11234}Y
+ X\x{11234}YZ
+ X\x{11234}\x{512}YZ
+ *** Failers
+ X\x{11234}
+
+/a\Cb/8
+ aXb
+ a\nb
+
+/a\C\Cb/8
+ a\x{12257}b
+ a\x{12257}\x{11234}b
+ ** Failers
+ a\x{100}b
+
+/ab\Cde/8
+ abXde
+
+/-- Check maximum character size --/
+
+/\x{ffff}/8DZ
+
+/\x{10000}/8DZ
+
+/\x{100}/8DZ
+
+/\x{1000}/8DZ
+
+/\x{10000}/8DZ
+
+/\x{100000}/8DZ
+
+/\x{10ffff}/8DZ
+
+/[\x{ff}]/8DZ
+
+/[\x{100}]/8DZ
+
+/\x80/8DZ
+
+/\xff/8DZ
+
+/\x{D55c}\x{ad6d}\x{C5B4}/DZ8
+ \x{D55c}\x{ad6d}\x{C5B4}
+
+/\x{65e5}\x{672c}\x{8a9e}/DZ8
+ \x{65e5}\x{672c}\x{8a9e}
+
+/\x{80}/DZ8
+
+/\x{084}/DZ8
+
+/\x{104}/DZ8
+
+/\x{861}/DZ8
+
+/\x{212ab}/DZ8
+
+/-- This one is here not because it's different to Perl, but because the way
+the captured single-byte is displayed. (In Perl it becomes a character, and you
+can't tell the difference.) --/
+
+/X(\C)(.*)/8
+ X\x{1234}
+ X\nabc
+
+/-- This one is here because Perl gives out a grumbly error message (quite
+correctly, but that messes up comparisons). --/
+
+/a\Cb/8
+ *** Failers
+ a\x{100}b
+
+/[^ab\xC0-\xF0]/8SDZ
+ \x{f1}
+ \x{bf}
+ \x{100}
+ \x{1000}
+ *** Failers
+ \x{c0}
+ \x{f0}
+
+/Ā{3,4}/8SDZ
+ \x{100}\x{100}\x{100}\x{100\x{100}
+
+/(\x{100}+|x)/8SDZ
+
+/(\x{100}*a|x)/8SDZ
+
+/(\x{100}{0,2}a|x)/8SDZ
+
+/(\x{100}{1,2}a|x)/8SDZ
+
+/\x{100}/8DZ
+
+/a\x{100}\x{101}*/8DZ
+
+/a\x{100}\x{101}+/8DZ
+
+/[^\x{c4}]/DZ
+
+/[\x{100}]/8DZ
+ \x{100}
+ Z\x{100}
+ \x{100}Z
+ *** Failers
+
+/[\xff]/DZ8
+ >\x{ff}<
+
+/[^\xff]/8DZ
+
+/\x{100}abc(xyz(?1))/8DZ
+
+/\777/8I
+ \x{1ff}
+ \777
+
+/\x{100}+\x{200}/8DZ
+
+/\x{100}+X/8DZ
+
+/^[\QĀ\E-\QŐ\E/BZ8
+
+/X/8
+ \x{d800}
+ \x{d800}\?
+ \x{da00}
+ \x{da00}\?
+ \x{dc00}
+ \x{dc00}\?
+ \x{de00}
+ \x{de00}\?
+ \x{dfff}
+ \x{dfff}\?
+ \x{110000}
+ \x{d800}\x{1234}
+
+/(*UTF16)\x{11234}/
+ abcd\x{11234}pqr
+
+/(*UTF)\x{11234}/I
+ abcd\x{11234}pqr
+
+/(*UTF-32)\x{11234}/
+ abcd\x{11234}pqr
+
+/(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I
+
+/(*CRLF)(*UTF32)(*BSR_UNICODE)a\Rb/I
+
+/\h/SI8
+ ABC\x{09}
+ ABC\x{20}
+ ABC\x{a0}
+ ABC\x{1680}
+ ABC\x{180e}
+ ABC\x{2000}
+ ABC\x{202f}
+ ABC\x{205f}
+ ABC\x{3000}
+
+/\v/SI8
+ ABC\x{0a}
+ ABC\x{0b}
+ ABC\x{0c}
+ ABC\x{0d}
+ ABC\x{85}
+ ABC\x{2028}
+
+/\h*A/SI8
+ CDBABC
+ \x{2000}ABC
+
+/\R*A/SI8
+ CDBABC
+ \x{2028}A
+
+/\v+A/SI8
+
+/\s?xxx\s/8SI
+
+/\sxxx\s/I8ST1
+ AB\x{85}xxx\x{a0}XYZ
+ AB\x{a0}xxx\x{85}XYZ
+
+/\S \S/I8ST1
+ \x{a2} \x{84}
+ A Z
+
+/a+/8
+ a\x{123}aa\>1
+ a\x{123}aa\>2
+ a\x{123}aa\>3
+ a\x{123}aa\>4
+ a\x{123}aa\>5
+ a\x{123}aa\>6
+
+/\x{1234}+/iS8I
+
+/\x{1234}+?/iS8I
+
+/\x{1234}++/iS8I
+
+/\x{1234}{2}/iS8I
+
+/[^\x{c4}]/8DZ
+
+/X+\x{200}/8DZ
+
+/\R/SI8
+
+/-- Check bad offset --/
+
+/a/8
+ \x{10000}\>1
+ \x{10000}ab\>1
+ \x{10000}ab\>2
+ \x{10000}ab\>3
+ \x{10000}ab\>4
+ \x{10000}ab\>5
+
+//8
+
+/\w+\x{C4}/8BZ
+ a\x{C4}\x{C4}
+
+/\w+\x{C4}/8BZT1
+ a\x{C4}\x{C4}
+
+/\W+\x{C4}/8BZ
+ !\x{C4}
+
+/\W+\x{C4}/8BZT1
+ !\x{C4}
+
+/\W+\x{A1}/8BZ
+ !\x{A1}
+
+/\W+\x{A1}/8BZT1
+ !\x{A1}
+
+/X\s+\x{A0}/8BZ
+ X\x20\x{A0}\x{A0}
+
+/X\s+\x{A0}/8BZT1
+ X\x20\x{A0}\x{A0}
+
+/\S+\x{A0}/8BZ
+ X\x{A0}\x{A0}
+
+/\S+\x{A0}/8BZT1
+ X\x{A0}\x{A0}
+
+/\x{a0}+\s!/8BZ
+ \x{a0}\x20!
+
+/\x{a0}+\s!/8BZT1
+ \x{a0}\x20!
+
+/(*UTF)abc/9
+
+/abc/89
+
+/-- End of testinput18 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput19 b/ext/pcre/pcrelib/testdata/testinput19
new file mode 100644
index 0000000000..00d80203f0
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput19
@@ -0,0 +1,22 @@
+/-- This set of tests is for Unicode property support, relevant only to the
+ 16- and 32-bit library. --/
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ
+
+/AB\x{1fb0}/8DZ
+
+/AB\x{1fb0}/8DZi
+
+/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI
+ \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}
+ \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f}
+
+/[ⱥ]/8iBZ
+
+/[^ⱥ]/8iBZ
+
+/[[:blank:]]/WBZ
+
+/-- End of testinput19 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput2 b/ext/pcre/pcrelib/testdata/testinput2
index 9670104e6a..00924ee98f 100644
--- a/ext/pcre/pcrelib/testdata/testinput2
+++ b/ext/pcre/pcrelib/testdata/testinput2
@@ -7,6 +7,8 @@
NOTE: This is a non-UTF set of tests. When UTF support is needed, use
test 5, and if Unicode Property Support is needed, use test 7. --/
+
+< forbid 8W
/(a)b|/I
@@ -313,12 +315,6 @@
*** Failers
fooabar
-/This one is here because Perl 5.005_02 doesn't fail it/I
-
-/^(a)?(?(1)a|b)+$/I
- *** Failers
- a
-
/This one is here because Perl behaves differently; see also the following/I
/^(a\1?){4}$/I
@@ -835,7 +831,13 @@
/x++/DZ
-/x{1,3}+/DZ
+/x{1,3}+/BZO
+
+/x{1,3}+/BZOi
+
+/[^x]{1,3}+/BZO
+
+/[^x]{1,3}+/BZOi
/(x)*+/DZ
@@ -1501,6 +1503,8 @@
a2b\CA
** Failers
a1b\CZ\CA
+
+/(?|(?<a>)(?<b>)(?<a>)|(?<a>)(?<b>)(?<a>))/IJ
/^(?P<A>a)(?P<A>b)/IJ
ab\CA
@@ -1941,10 +1945,7 @@ a random value. /Ix
/(?<A> (?'B' abc (?(R) (?(R&A)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x
abcabc1Xabc2XabcXabcabc
-/(?<A> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x
-
-/(?<1> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x
- abcabc1Xabc2XabcXabcabc
+/(?<A> (?'B' abc (?(R) (?(R&C)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x
/^(?(DEFINE) abc | xyz ) /x
@@ -2061,7 +2062,7 @@ a random value. /Ix
/^(a)\g{3/
-/^(a)\g{4a}/
+/^(a)\g{aa}/
/^a.b/<lf>
a\rb
@@ -2516,7 +2517,10 @@ a random value. /Ix
** Failers
ab
-/a(?!)+b/
+/a(?!)b/BZ
+
+/(?!)?a/BZ
+ ab
/a(*FAIL)+b/
@@ -2541,7 +2545,9 @@ a random value. /Ix
abcxypqr\Y
/(*NO_START_OPT)xyz/C
- abcxyz
+ abcxyz
+
+/(*NO_AUTO_POSSESS)a+b/BZ
/xyz/CY
abcxyz
@@ -2939,7 +2945,7 @@ a random value. /Ix
xxxxabcde\P
xxxxabcde\P\P
-/-- This is not in the Perl >= 5.10 test because Perl seems currently to be
+/-- This is not in the Perl-compatible test because Perl seems currently to be
broken and not behaving as specified in that it *does* bumpalong after
hitting (*COMMIT). --/
@@ -2985,28 +2991,12 @@ a random value. /Ix
/^(?&t)*(?(DEFINE)(?<t>.))$/BZ
-/ -- The first four of these are not in the Perl >= 5.10 test because Perl
- documents that the use of \K in assertions is "not well defined". The
- last is here because Perl gives the match as "b" rather than "ab". I
+/ -- This one is here because Perl gives the match as "b" rather than "ab". I
believe this to be a Perl bug. --/
-/(?=a\Kb)ab/
- ab
-
-/(?!a\Kb)ac/
- ac
-
-/^abc(?<=b\Kc)d/
- abcd
-
-/^abc(?<!b\Kq)d/
- abcd
-
/(?>a\Kb)z|(ab)/
ab
-/----------------------/
-
/(?P<L1>(?P<L2>0|)|(?P>L2)(?P>L1))/
/abc(*MARK:)pqr/
@@ -3021,7 +3011,7 @@ a random value. /Ix
/A(*COMMIT)B/+K
ACABX
-/--- These should be different, but in Perl 5.11 are not, which I think
+/--- These should be different, but in Perl they are not, which I think
is a bug in Perl. ---/
/A(*THEN)B|A(*THEN)C/K
@@ -3030,12 +3020,6 @@ a random value. /Ix
/A(*PRUNE)B|A(*PRUNE)C/K
AC
-/--- This should fail; the SKIP advances by one, but when we get to AC, the
- PRUNE kills it. Perl behaves differently. ---/
-
-/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK
- AAAC
-
/--- Mark names can be duplicated. Perl doesn't give a mark for this one,
though PCRE does. ---/
@@ -3061,7 +3045,7 @@ with \Y. ---/
/^(ab (c+(*FAIL)cd) | xyz)/x
abcccd
-/--- Perl 5.11 gets some of these wrong ---/
+/--- Perl gets some of these wrong ---/
/(?>.(*ACCEPT))*?5/
abcde
@@ -3121,14 +3105,6 @@ with \Y. ---/
/X\H++\R/BZ
X\x0d\x0a
-/-- Perl treats this one differently, not failing the second string. I believe
- that is a bug in Perl. --/
-
-/^((abc|abcx)(*THEN)y|abcd)/
- abcd
- *** Failers
- abcxy
-
/(?<=abc)def/
abc\P\P
@@ -3427,7 +3403,7 @@ with \Y. ---/
/\btype\b\W*?\btext\b\W*?\bjavascript\b|\burl\b\W*?\bshell:|<input\b.*?\btype\b\W*?\bimage\b|\bonkeyup\b\W*?\=/IS
-/a(*SKIP)c|b(*ACCEPT)|/+SI
+/a(*SKIP)c|b(*ACCEPT)|/+S!I
a
/a(*SKIP)c|b(*ACCEPT)cd(*ACCEPT)|x/SI
@@ -3453,52 +3429,6 @@ with \Y. ---/
/a(?:.(*THEN:ABC))*?a/ims
\Mabbbbbbbbbbbbbbbbbbbbba
-/-- These tests are in agreement with development Perl 5.015, which has fixed
- some things, but they don't all work with 5.012, so they aren't in the
- Perl-compatible tests. Those after the first come from Perl's own test
- files. --/
-
-/^((yes|no)(*THEN)(*F))?/
- yes
-
-/(A (.*) C? (*THEN) | A D) (*FAIL)/x
-AbcdCBefgBhiBqz
-
-/(A (.*) C? (*THEN) | A D) z/x
-AbcdCBefgBhiBqz
-
-/(A (.*) C? (*THEN) | A D) \s* (*FAIL)/x
-AbcdCBefgBhiBqz
-
-/(A (.*) C? (*THEN) | A D) \s* z/x
-AbcdCBefgBhiBqz
-
-/(A (.*) (?:C|) (*THEN) | A D) (*FAIL)/x
-AbcdCBefgBhiBqz
-
-/(A (.*) (?:C|) (*THEN) | A D) z/x
-AbcdCBefgBhiBqz
-
-/(A (.*) C{0,6} (*THEN) | A D) (*FAIL)/x
-AbcdCBefgBhiBqz
-
-/(A (.*) C{0,6} (*THEN) | A D) z/x
-AbcdCBefgBhiBqz
-
-/(A (.*) (CE){0,6} (*THEN) | A D) (*FAIL)/x
-AbcdCEBefgBhiBqz
-
-/(A (.*) (CE){0,6} (*THEN) | A D) z/x
-AbcdCEBefgBhiBqz
-
-/(A (.*) (CE*){0,6} (*THEN) | A D) (*FAIL)/x
-AbcdCBefgBhiBqz
-
-/(A (.*) (CE*){0,6} (*THEN) | A D) z/x
-AbcdCBefgBhiBqz
-
-/-----------------------------------------------/
-
/^(?>a+)(?>(z+))\w/BZ
aaaazzzzb
** Failers
@@ -3564,6 +3494,8 @@ AbcdCBefgBhiBqz
/a[B-\Nc]/
+/a[B\Nc]/
+
/(a)(?2){0,1999}?(b)/
/(a)(?(DEFINE)(b))(?2){0,1999}?(?2)/
@@ -3751,24 +3683,9 @@ replaced by single letters. --/
\r\r\r\P
\r\r\r\P\P
-/-- These two are here because Perl does not match: it seems to allow the
-COMMIT to escape from the assertion. --/
-
-/(?=a(*COMMIT)b|ac)ac|ac/
- ac
-
-/(?=a(*COMMIT)b|(ac)) ac | (a)c/x
- ac
-
"AB(C(D))(E(F))?(?(?=\2)(?=\4))"
ABCDGHI\O03
-/-- This one is here because Perl does not confine the *COMMIT to the
-assertion, and therefore fails the entire subroutine call. --/
-
-/((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/
- ac
-
/-- These are all run as real matches in test 1; here we are just checking the
settings of the anchored and startline bits. --/
@@ -3810,4 +3727,322 @@ settings of the anchored and startline bits. --/
/.?/S!I
+/(?:(a)+(?C1)bb|aa(?C2)b)/
+ aab\C+
+
+/(?:(a)++(?C1)bb|aa(?C2)b)/
+ aab\C+
+
+/(?:(?>(a))(?C1)bb|aa(?C2)b)/
+ aab\C+
+
+/(?:(?1)(?C1)x|ab(?C2))((a)){0}/
+ aab\C+
+
+/(?1)(?C1)((a)(?C2)){0}/
+ aab\C+
+
+/(?:(a)+(?C1)bb|aa(?C2)b)++/
+ aab\C+
+ aab\C+\O2
+
+/(ab)x|ab/
+ ab\O3
+ ab\O2
+
+/(ab)/
+ ab\O3
+ ab\O2
+
+/(?<=123)(*MARK:xx)abc/K
+ xxxx123a\P\P
+ xxxx123a\P
+
+/123\Kabc/
+ xxxx123a\P\P
+ xxxx123a\P
+
+/^(?(?=a)aa|bb)/C
+ bb
+
+/(?C1)^(?C2)(?(?C99)(?=(?C3)a(?C4))(?C5)a(?C6)a(?C7)|(?C8)b(?C9)b(?C10))(?C11)/
+ bb
+
+/-- Perl seems to have a bug with this one --/
+
+/aaaaa(*COMMIT)(*PRUNE)b|a+c/
+ aaaaaac
+
+/-- Here are some that Perl treats differently because of the way it handles
+backtracking verbs. --/
+
+ /(?!a(*COMMIT)b)ac|ad/
+ ac
+ ad
+
+/^(?!a(*THEN)b|ac)../
+ ac
+ ad
+
+/^(?=a(*THEN)b|ac)/
+ ac
+
+/\A.*?(?:a|b(*THEN)c)/
+ ba
+
+/\A.*?(?:a|b(*THEN)c)++/
+ ba
+
+/\A.*?(?:a|b(*THEN)c|d)/
+ ba
+
+/(?:(a(*MARK:X)a+(*SKIP:X)b)){0}(?:(?1)|aac)/
+ aac
+
+/\A.*?(a|b(*THEN)c)/
+ ba
+
+/^(A(*THEN)B|A(*THEN)D)/
+ AD
+
+/(?!b(*THEN)a)bn|bnn/
+ bnn
+
+/(?(?=b(*SKIP)a)bn|bnn)/
+ bnn
+
+/(?=b(*THEN)a|)bn|bnn/
+ bnn
+
+/-------------------------/
+
+/(*LIMIT_MATCH=12bc)abc/
+
+/(*LIMIT_MATCH=4294967290)abc/
+
+/(*LIMIT_RECURSION=4294967280)abc/I
+
+/(a+)*zz/
+ aaaaaaaaaaaaaz
+ aaaaaaaaaaaaaz\q3000
+
+/(a+)*zz/S-
+ aaaaaaaaaaaaaz\Q10
+
+/(*LIMIT_MATCH=3000)(a+)*zz/I
+ aaaaaaaaaaaaaz
+ aaaaaaaaaaaaaz\q60000
+
+/(*LIMIT_MATCH=60000)(*LIMIT_MATCH=3000)(a+)*zz/I
+ aaaaaaaaaaaaaz
+
+/(*LIMIT_MATCH=60000)(a+)*zz/I
+ aaaaaaaaaaaaaz
+ aaaaaaaaaaaaaz\q3000
+
+/(*LIMIT_RECURSION=10)(a+)*zz/IS-
+ aaaaaaaaaaaaaz
+ aaaaaaaaaaaaaz\Q1000
+
+/(*LIMIT_RECURSION=10)(*LIMIT_RECURSION=1000)(a+)*zz/IS-
+ aaaaaaaaaaaaaz
+
+/(*LIMIT_RECURSION=1000)(a+)*zz/IS-
+ aaaaaaaaaaaaaz
+ aaaaaaaaaaaaaz\Q10
+
+/-- This test causes a segfault with Perl 5.18.0 --/
+
+/^(?=(a)){0}b(?1)/
+ backgammon
+
+/(?|(?<n>f)|(?<n>b))/JI
+
+/(?<a>abc)(?<a>z)\k<a>()/JDZS
+
+/a*[bcd]/BZ
+
+/[bcd]*a/BZ
+
+/-- A complete set of tests for auto-possessification of character types --/
+
+/\D+\D \D+\d \D+\S \D+\s \D+\W \D+\w \D+. \D+\C \D+\R \D+\H \D+\h \D+\V \D+\v \D+\Z \D+\z \D+$/BZx
+
+/\d+\D \d+\d \d+\S \d+\s \d+\W \d+\w \d+. \d+\C \d+\R \d+\H \d+\h \d+\V \d+\v \d+\Z \d+\z \d+$/BZx
+
+/\S+\D \S+\d \S+\S \S+\s \S+\W \S+\w \S+. \S+\C \S+\R \S+\H \S+\h \S+\V \S+\v \S+\Z \S+\z \S+$/BZx
+
+/\s+\D \s+\d \s+\S \s+\s \s+\W \s+\w \s+. \s+\C \s+\R \s+\H \s+\h \s+\V \s+\v \s+\Z \s+\z \s+$/BZx
+
+/\W+\D \W+\d \W+\S \W+\s \W+\W \W+\w \W+. \W+\C \W+\R \W+\H \W+\h \W+\V \W+\v \W+\Z \W+\z \W+$/BZx
+
+/\w+\D \w+\d \w+\S \w+\s \w+\W \w+\w \w+. \w+\C \w+\R \w+\H \w+\h \w+\V \w+\v \w+\Z \w+\z \w+$/BZx
+
+/\C+\D \C+\d \C+\S \C+\s \C+\W \C+\w \C+. \C+\C \C+\R \C+\H \C+\h \C+\V \C+\v \C+\Z \C+\z \C+$/BZx
+
+/\R+\D \R+\d \R+\S \R+\s \R+\W \R+\w \R+. \R+\C \R+\R \R+\H \R+\h \R+\V \R+\v \R+\Z \R+\z \R+$/BZx
+
+/\H+\D \H+\d \H+\S \H+\s \H+\W \H+\w \H+. \H+\C \H+\R \H+\H \H+\h \H+\V \H+\v \H+\Z \H+\z \H+$/BZx
+
+/\h+\D \h+\d \h+\S \h+\s \h+\W \h+\w \h+. \h+\C \h+\R \h+\H \h+\h \h+\V \h+\v \h+\Z \h+\z \h+$/BZx
+
+/\V+\D \V+\d \V+\S \V+\s \V+\W \V+\w \V+. \V+\C \V+\R \V+\H \V+\h \V+\V \V+\v \V+\Z \V+\z \V+$/BZx
+
+/\v+\D \v+\d \v+\S \v+\s \v+\W \v+\w \v+. \v+\C \v+\R \v+\H \v+\h \v+\V \v+\v \v+\Z \v+\z \v+$/BZx
+
+/ a+\D a+\d a+\S a+\s a+\W a+\w a+. a+\C a+\R a+\H a+\h a+\V a+\v a+\Z a+\z a+$/BZx
+
+/\n+\D \n+\d \n+\S \n+\s \n+\W \n+\w \n+. \n+\C \n+\R \n+\H \n+\h \n+\V \n+\v \n+\Z \n+\z \n+$/BZx
+
+/ .+\D .+\d .+\S .+\s .+\W .+\w .+. .+\C .+\R .+\H .+\h .+\V .+\v .+\Z .+\z .+$/BZx
+
+/ .+\D .+\d .+\S .+\s .+\W .+\w .+. .+\C .+\R .+\H .+\h .+\V .+\v .+\Z .+\z .+$/BZxs
+
+/\D+$ \d+$ \S+$ \s+$ \W+$ \w+$ \C+$ \R+$ \H+$ \h+$ \V+$ \v+$ a+$ \n+$ .+$ .+$/BZxm
+
+/(?=a+)a(a+)++a/BZ
+
+/a+(bb|cc)a+(?:bb|cc)a+(?>bb|cc)a+(?:bb|cc)+a+(aa)a+(?:bb|aa)/BZ
+
+/a+(bb|cc)?#a+(?:bb|cc)??#a+(?:bb|cc)?+#a+(?:bb|cc)*#a+(bb|cc)?a#a+(?:aa)?/BZ
+
+/a+(?:bb)?a#a+(?:|||)#a+(?:|b)a#a+(?:|||)?a/BZ
+
+/[ab]*/BZ
+ aaaa
+
+/[ab]*?/BZ
+ aaaa
+
+/[ab]?/BZ
+ aaaa
+
+/[ab]??/BZ
+ aaaa
+
+/[ab]+/BZ
+ aaaa
+
+/[ab]+?/BZ
+ aaaa
+
+/[ab]{2,3}/BZ
+ aaaa
+
+/[ab]{2,3}?/BZ
+ aaaa
+
+/[ab]{2,}/BZ
+ aaaa
+
+/[ab]{2,}?/BZ
+ aaaa
+
+/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/BZ
+
+/[a-d]{5,12}[e-z0-9]*#[^a-z]+[b-y]*a[2-7]?[^0-9a-z]+/BZ
+
+/[a-z]*\s#[ \t]?\S#[a-c]*\S#[C-G]+?\d#[4-8]*\D#[4-9,]*\D#[!$]{0,5}\w#[M-Xf-l]+\W#[a-c,]?\W/BZ
+
+/a+(aa|bb)*c#a*(bb|cc)*a#a?(bb|cc)*d#[a-f]*(g|hh)*f/BZ
+
+/[a-f]*(g|hh|i)*i#[a-x]{4,}(y{0,6})*y#[a-k]+(ll|mm)+n/BZ
+
+/[a-f]*(?>gg|hh)+#[a-f]*(?>gg|hh)?#[a-f]*(?>gg|hh)*a#[a-f]*(?>gg|hh)*h/BZ
+
+/[a-c]*d/DZS
+
+/[a-c]+d/DZS
+
+/[a-c]?d/DZS
+
+/[a-c]{4,6}d/DZS
+
+/[a-c]{0,6}d/DZS
+
+/-- End of special auto-possessive tests --/
+
+/^A\o{1239}B/
+ A\123B
+
+/^A\oB/
+
+/^A\x{zz}B/
+
+/^A\x{12Z/
+
+/^A\x{/
+
+/[ab]++/BZO
+
+/[^ab]*+/BZO
+
+/a{4}+/BZO
+
+/a{4}+/BZOi
+
+/[a-[:digit:]]+/
+
+/[A-[:digit:]]+/
+
+/[a-[.xxx.]]+/
+
+/[a-[=xxx=]]+/
+
+/[a-[!xxx!]]+/
+
+/[A-[!xxx!]]+/
+ A]]]
+
+/[a-\d]+/
+
+/(?<0abc>xx)/
+
+/(?&1abc)xx(?<1abc>y)/
+
+/(?<ab-cd>xx)/
+
+/(?'0abc'xx)/
+
+/(?P<0abc>xx)/
+
+/\k<5ghj>/
+
+/\k'5ghj'/
+
+/\k{2fgh}/
+
+/(?P=8yuki)/
+
+/\g{4df}/
+
+/(?&1abc)xx(?<1abc>y)/
+
+/(?P>1abc)xx(?<1abc>y)/
+
+/\g'3gh'/
+
+/\g<5fg>/
+
+/(?(<4gh>)abc)/
+
+/(?('4gh')abc)/
+
+/(?(4gh)abc)/
+
+/(?(R&6yh)abc)/
+
+/-- Test the ugly "start or end of word" compatibility syntax --/
+
+/[[:<:]]red[[:>:]]/BZ
+ little red riding hood
+ a /red/ thing
+ red is a colour
+ put it all on red
+ ** Failers
+ no reduction
+ Alfred Winifred
+
+/[a[:<:]] should give error/
+
/-- End of testinput2 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput20 b/ext/pcre/pcrelib/testdata/testinput20
new file mode 100644
index 0000000000..2a6b8f23f4
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput20
@@ -0,0 +1,19 @@
+/-- These DFA tests are for the handling of characters greater than 255 in
+ 16- or 32-bit, non-UTF mode. --/
+
+/^\x{ffff}+/i
+ \x{ffff}
+
+/^\x{ffff}?/i
+ \x{ffff}
+
+/^\x{ffff}*/i
+ \x{ffff}
+
+/^\x{ffff}{3}/i
+ \x{ffff}\x{ffff}\x{ffff}
+
+/^\x{ffff}{0,3}/i
+ \x{ffff}
+
+/-- End of testinput20 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput21 b/ext/pcre/pcrelib/testdata/testinput21
new file mode 100644
index 0000000000..30895eef2d
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput21
@@ -0,0 +1,26 @@
+/-- Tests for reloading pre-compiled patterns. The first one gives an error
+right away, and can be any old pattern compiled in 8-bit mode ("abc" is
+typical). The others require the link size to be 2. */x
+
+<!testsaved8
+
+%-- Generated from:
+ /^[aL](?P<name>(?:[AaLl]+)[^xX-]*?)(?P<other>[\x{150}-\x{250}\x{300}]|
+ [^\x{800}aAs-uS-U\x{d800}-\x{dfff}])++[^#\b\x{500}\x{1000}]{3,5}$
+ /x
+
+ In 16-bit mode with options: S>testdata/saved16LE-1
+ FS>testdata/saved16BE-1
+ In 32-bit mode with options: S>testdata/saved32LE-1
+ FS>testdata/saved32BE-1
+--%x
+
+<!testsaved16LE-1
+
+<!testsaved16BE-1
+
+<!testsaved32LE-1
+
+<!testsaved32BE-1
+
+/-- End of testinput21 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput22 b/ext/pcre/pcrelib/testdata/testinput22
new file mode 100644
index 0000000000..ca408dbee9
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput22
@@ -0,0 +1,23 @@
+/-- Tests for reloading pre-compile patterns with UTF-16 or UTF-32 support. */
+
+%-- Generated from:
+ /(?P<cbra1>[aZ\x{400}-\x{10ffff}]{4,}
+ [\x{f123}\x{10039}\x{20000}-\x{21234}]?|
+ [A-Cx-z\x{100000}-\x{1000a7}\x{101234}])
+ (?<cb2>[^az])/x
+
+ In 16-bit mode with options: S8>testdata/saved16LE-2
+ FS8>testdata/saved16BE-2
+ In 32-bit mode with options: S8>testdata/saved32LE-2
+ FS8>testdata/saved32BE-2
+--%8x
+
+<!testsaved16LE-2
+
+<!testsaved16BE-2
+
+<!testsaved32LE-2
+
+<!testsaved32BE-2
+
+/-- End of testinput22 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput23 b/ext/pcre/pcrelib/testdata/testinput23
new file mode 100644
index 0000000000..0fdbae7c57
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput23
@@ -0,0 +1,20 @@
+/-- Tests for the 16-bit library only */
+
+< forbid 8W
+
+/-- Check maximum non-UTF character size --/
+
+/\x{ffff}/
+ A\x{ffff}B
+
+/\x{10000}/
+
+/\o{20000}/
+
+/-- Check character ranges --/
+
+/[\H]/BZSI
+
+/[\V]/BZSI
+
+/-- End of testinput23 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput24 b/ext/pcre/pcrelib/testdata/testinput24
new file mode 100644
index 0000000000..23eb84e55d
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput24
@@ -0,0 +1,11 @@
+/-- Tests for the 16-bit library with UTF-16 support only */
+
+< forbid W
+
+/bad/8
+ \x{d800}
+
+/short/8
+ \P\P\x{d800}
+
+/-- End of testinput24 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput25 b/ext/pcre/pcrelib/testdata/testinput25
new file mode 100644
index 0000000000..ce9d9e19a4
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput25
@@ -0,0 +1,44 @@
+/-- Tests for the 32-bit library only */
+
+< forbid 8w
+
+/-- Check maximum character size --/
+
+/\x{110000}/
+
+/\x{7fffffff}/
+
+/\x{80000000}/
+
+/\x{ffffffff}/
+
+/\x{100000000}/
+
+/\o{17777777777}/
+
+/\o{20000000000}/
+
+/\o{37777777777}/
+
+/\o{40000000000}/
+
+/\x{7fffffff}\x{7fffffff}/I
+
+/\x{80000000}\x{80000000}/I
+
+/\x{ffffffff}\x{ffffffff}/I
+
+/-- Non-UTF characters --/
+
+/\C{2,3}/
+ \x{400000}\x{400001}\x{400002}\x{400003}
+
+/\x{400000}\x{800000}/iDZ
+
+/-- Check character ranges --/
+
+/[\H]/BZSI
+
+/[\V]/BZSI
+
+/-- End of testinput25 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput26 b/ext/pcre/pcrelib/testdata/testinput26
new file mode 100644
index 0000000000..6b56ac1cc5
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinput26
@@ -0,0 +1,14 @@
+/-- Tests for the 32-bit library with UTF-32 support only */
+
+< forbid W
+
+/-- Non-UTF characters --/
+
+/\x{110000}/8
+
+/\o{4200000}/8
+
+/\C/8
+ \x{110000}
+
+/-- End of testinput26 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput3 b/ext/pcre/pcrelib/testdata/testinput3
index 6fea2f5b3b..1d2e855386 100644
--- a/ext/pcre/pcrelib/testdata/testinput3
+++ b/ext/pcre/pcrelib/testdata/testinput3
@@ -1,6 +1,8 @@
/-- This set of tests checks local-specific features, using the fr_FR locale.
It is not Perl-compatible. There is different version called wintestinput3
f or use on Windows, where the locale is called "french". --/
+
+< forbid 8W
/^[\w]+/
*** Failers
diff --git a/ext/pcre/pcrelib/testdata/testinput4 b/ext/pcre/pcrelib/testdata/testinput4
index c7bb370cfd..983f7a119b 100644
--- a/ext/pcre/pcrelib/testdata/testinput4
+++ b/ext/pcre/pcrelib/testdata/testinput4
@@ -1,6 +1,8 @@
/-- This set of tests is for UTF support, excluding Unicode properties. It is
compatible with all versions of Perl >= 5.10 and both the 8-bit and 16-bit
PCRE libraries. --/
+
+< forbid 9?=ABCDEFfGILMNPTUWXZ<
/a.b/8
acb
@@ -621,4 +623,97 @@
/a(*:a£b)/8K
abc
+/-- Noncharacters --/
+
+/./8
+ \x{fffe}
+ \x{ffff}
+ \x{1fffe}
+ \x{1ffff}
+ \x{2fffe}
+ \x{2ffff}
+ \x{3fffe}
+ \x{3ffff}
+ \x{4fffe}
+ \x{4ffff}
+ \x{5fffe}
+ \x{5ffff}
+ \x{6fffe}
+ \x{6ffff}
+ \x{7fffe}
+ \x{7ffff}
+ \x{8fffe}
+ \x{8ffff}
+ \x{9fffe}
+ \x{9ffff}
+ \x{afffe}
+ \x{affff}
+ \x{bfffe}
+ \x{bffff}
+ \x{cfffe}
+ \x{cffff}
+ \x{dfffe}
+ \x{dffff}
+ \x{efffe}
+ \x{effff}
+ \x{ffffe}
+ \x{fffff}
+ \x{10fffe}
+ \x{10ffff}
+ \x{fdd0}
+ \x{fdd1}
+ \x{fdd2}
+ \x{fdd3}
+ \x{fdd4}
+ \x{fdd5}
+ \x{fdd6}
+ \x{fdd7}
+ \x{fdd8}
+ \x{fdd9}
+ \x{fdda}
+ \x{fddb}
+ \x{fddc}
+ \x{fddd}
+ \x{fdde}
+ \x{fddf}
+ \x{fde0}
+ \x{fde1}
+ \x{fde2}
+ \x{fde3}
+ \x{fde4}
+ \x{fde5}
+ \x{fde6}
+ \x{fde7}
+ \x{fde8}
+ \x{fde9}
+ \x{fdea}
+ \x{fdeb}
+ \x{fdec}
+ \x{fded}
+ \x{fdee}
+ \x{fdef}
+
+/^\d*\w{4}/8
+ 1234
+ 123
+
+/^[^b]*\w{4}/8
+ aaaa
+ aaa
+
+/^[^b]*\w{4}/8i
+ aaaa
+ aaa
+
+/^\x{100}*.{4}/8
+ \x{100}\x{100}\x{100}\x{100}
+ \x{100}\x{100}\x{100}
+
+/^\x{100}*.{4}/8i
+ \x{100}\x{100}\x{100}\x{100}
+ \x{100}\x{100}\x{100}
+
+/^a+[a\x{200}]/8
+ aa
+
/-- End of testinput4 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput5 b/ext/pcre/pcrelib/testdata/testinput5
index 642749c315..9e9a22a1a1 100644
--- a/ext/pcre/pcrelib/testdata/testinput5
+++ b/ext/pcre/pcrelib/testdata/testinput5
@@ -1,21 +1,37 @@
/-- This set of tests checks the API, internals, and non-Perl stuff for UTF
support, excluding Unicode properties. However, tests that give different
results in 8-bit and 16-bit modes are excluded (see tests 16 and 17). --/
+
+< forbid W
/\x{110000}/8DZ
+/\o{4200000}/8DZ
+
/\x{ffffffff}/8
+/\o{37777777777}/8
+
/\x{100000000}/8
+/\o{77777777777}/8
+
/\x{d800}/8
+/\o{154000}/8
+
/\x{dfff}/8
+/\o{157777}/8
+
/\x{d7ff}/8
+/\o{153777}/8
+
/\x{e000}/8
+/\o{170000}/8
+
/^\x{100}a\x{1234}/8
\x{100}a\x{1234}bcd
@@ -769,4 +785,7 @@
/\ud800/<JS>8
+/^a+[a\x{200}]/8BZ
+ aa
+
/-- End of testinput5 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput6 b/ext/pcre/pcrelib/testdata/testinput6
index a4bfb3c19b..1e450be04d 100644
--- a/ext/pcre/pcrelib/testdata/testinput6
+++ b/ext/pcre/pcrelib/testdata/testinput6
@@ -1,5 +1,7 @@
/-- This set of tests is for Unicode property support. It is compatible with
Perl >= 5.15. --/
+
+< forbid 9?=ABCDEFfGILMNPTUXZ<
/^\pC\pL\pM\pN\pP\pS\pZ</8
\x7f\x{c0}\x{30f}\x{660}\x{66c}\x{f01}\x{1680}<
@@ -325,12 +327,6 @@
** Failers
abc
-/\p{Lu}/8i
- A
- aZ
- ** Failers
- abc
-
/\p{Ll}/8
a
Az
@@ -425,6 +421,7 @@
/^[\p{Arabic}]/8
\x{06e9}
\x{060b}
+ \x{061c}
** Failers
X\x{06e9}
@@ -882,6 +879,15 @@
\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X
\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X
+/\X*Z/8Y
+ A\x{300}
+
+/\X*(.)/8Y
+ A\x{1111}\x{ae4c}\x{1169}
+
+/\X?abc/8Y
+\xff\x7f\x00\x00\x03\x00\x41\xcc\x80\x41\x{300}\x61\x62\x63\x00\>06\?
+
/-- --/
/\x{1e9e}+/8i
@@ -1316,4 +1322,166 @@
/\x{017f}+/8i
\x{0053}\x{0073}\x{017f}
+/^\p{Any}*\d{4}/8
+ 1234
+ 123
+
+/^\X*\w{4}/8
+ 1234
+ 123
+
+/^A\s+Z/8W
+ A\x{2005}Z
+ A\x{85}\x{180e}\x{2005}Z
+
+/^A[\s]+Z/8W
+ A\x{2005}Z
+ A\x{85}\x{180e}\x{2005}Z
+
+/^[[:graph:]]+$/8W
+ Letter:ABC
+ Mark:\x{300}\x{1d172}\x{1d17b}
+ Number:9\x{660}
+ Punctuation:\x{66a},;
+ Symbol:\x{6de}<>\x{fffc}
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ \x{feff}
+ \x{fff9}\x{fffa}\x{fffb}
+ \x{110bd}
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ \x{e0001}
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+ ** Failers
+ \x{09}
+ \x{0a}
+ \x{1D}
+ \x{20}
+ \x{85}
+ \x{a0}
+ \x{61c}
+ \x{1680}
+ \x{180e}
+ \x{2028}
+ \x{2029}
+ \x{202f}
+ \x{2065}
+ \x{2066}
+ \x{2067}
+ \x{2068}
+ \x{2069}
+ \x{3000}
+ \x{e0002}
+ \x{e001f}
+ \x{e0080}
+
+/^[[:print:]]+$/8W
+ Space: \x{a0}
+ \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005}
+ \x{2006}\x{2007}\x{2008}\x{2009}\x{200a}
+ \x{202f}\x{205f}
+ \x{3000}
+ Letter:ABC
+ Mark:\x{300}\x{1d172}\x{1d17b}
+ Number:9\x{660}
+ Punctuation:\x{66a},;
+ Symbol:\x{6de}<>\x{fffc}
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ \x{180e}
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ \x{202f}
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ \x{feff}
+ \x{fff9}\x{fffa}\x{fffb}
+ \x{110bd}
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ \x{e0001}
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+ ** Failers
+ \x{09}
+ \x{1D}
+ \x{85}
+ \x{61c}
+ \x{2028}
+ \x{2029}
+ \x{2065}
+ \x{2066}
+ \x{2067}
+ \x{2068}
+ \x{2069}
+ \x{e0002}
+ \x{e001f}
+ \x{e0080}
+
+/^[[:punct:]]+$/8W
+ \$+<=>^`|~
+ !\"#%&'()*,-./:;?@[\\]_{}
+ \x{a1}\x{a7}
+ \x{37e}
+ ** Failers
+ abcde
+
+/^[[:^graph:]]+$/8W
+ \x{09}\x{0a}\x{1D}\x{20}\x{85}\x{a0}\x{61c}\x{1680}\x{180e}
+ \x{2028}\x{2029}\x{202f}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}
+ \x{3000}\x{e0002}\x{e001f}\x{e0080}
+ ** Failers
+ Letter:ABC
+ Mark:\x{300}\x{1d172}\x{1d17b}
+ Number:9\x{660}
+ Punctuation:\x{66a},;
+ Symbol:\x{6de}<>\x{fffc}
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ \x{feff}
+ \x{fff9}\x{fffa}\x{fffb}
+ \x{110bd}
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ \x{e0001}
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+
+/^[[:^print:]]+$/8W
+ \x{09}\x{1D}\x{85}\x{61c}\x{2028}\x{2029}\x{2065}\x{2066}\x{2067}
+ \x{2068}\x{2069}\x{e0002}\x{e001f}\x{e0080}
+ ** Failers
+ Space: \x{a0}
+ \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005}
+ \x{2006}\x{2007}\x{2008}\x{2009}\x{200a}
+ \x{202f}\x{205f}
+ \x{3000}
+ Letter:ABC
+ Mark:\x{300}\x{1d172}\x{1d17b}
+ Number:9\x{660}
+ Punctuation:\x{66a},;
+ Symbol:\x{6de}<>\x{fffc}
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ \x{180e}
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ \x{202f}
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ \x{feff}
+ \x{fff9}\x{fffa}\x{fffb}
+ \x{110bd}
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ \x{e0001}
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+
+/^[[:^punct:]]+$/8W
+ abcde
+ ** Failers
+ \$+<=>^`|~
+ !\"#%&'()*,-./:;?@[\\]_{}
+ \x{a1}\x{a7}
+ \x{37e}
+
/-- End of testinput6 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput7 b/ext/pcre/pcrelib/testdata/testinput7
index b265f1f9ac..9d14543635 100644
--- a/ext/pcre/pcrelib/testdata/testinput7
+++ b/ext/pcre/pcrelib/testdata/testinput7
@@ -100,11 +100,30 @@
/\p{Cc}{2}+/8BZ
+/^\p{Cf}/8
+ \x{180e}
+ \x{061c}
+ \x{2066}
+ \x{2067}
+ \x{2068}
+ \x{2069}
+
/^\p{Cs}/8
\?\x{dfff}
** Failers
\x{09f}
+/^\p{Mn}/8
+ \x{1a1b}
+
+/^\p{Pe}/8
+ \x{2309}
+ \x{230b}
+
+/^\p{Ps}/8
+ \x{2308}
+ \x{230a}
+
/^\p{Sc}+/8
$\x{a2}\x{a3}\x{a4}\x{a5}\x{a6}
\x{9f2}
@@ -116,15 +135,15 @@
\ \
\x{a0}
\x{1680}
- \x{180e}
\x{2000}
\x{2001}
** Failers
\x{2028}
\x{200d}
-/-- These four are here rather than in test 6 because Perl has problems with
- the negative versions of the properties. --/
+/-- These are here rather than in test 6 because Perl has problems with
+ the negative versions of the properties and behaves has changed how
+ it behaves for caseless matching. --/
/\p{^Lu}/8i
1234
@@ -149,6 +168,12 @@
a
\x{1d00}
+/\p{Lu}/8i
+ A
+ aZ
+ ** Failers
+ abc
+
/[\x{c0}\x{391}]/8i
\x{c0}
\x{e0}
@@ -668,5 +693,140 @@ of case for anything other than the ASCII letters. --/
/is{2}t/8i
iskt
+
+/-- This property is a PCRE special --/
+
+/^\p{Xuc}/8
+ $abc
+ @abc
+ `abc
+ \x{1234}abc
+ ** Failers
+ abc
+
+/^\p{Xuc}+/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\p{Xuc}+?/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\p{Xuc}+?\*/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\p{Xuc}++/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\p{Xuc}{3,5}/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\p{Xuc}{3,5}?/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^[\p{Xuc}]/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^[\p{Xuc}]+/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ ** Failers
+ \x{9f}
+
+/^\P{Xuc}/8
+ abc
+ ** Failers
+ $abc
+ @abc
+ `abc
+ \x{1234}abc
+
+/^[\P{Xuc}]/8
+ abc
+ ** Failers
+ $abc
+ @abc
+ `abc
+ \x{1234}abc
+
+/-- Some auto-possessification tests --/
+
+/\pN+\z/BZ
+
+/\PN+\z/BZ
+
+/\pN+/BZ
+
+/\PN+/BZ
+
+/\p{Any}+\p{Any} \p{Any}+\P{Any} \p{Any}+\p{L&} \p{Any}+\p{L} \p{Any}+\p{Lu} \p{Any}+\p{Han} \p{Any}+\p{Xan} \p{Any}+\p{Xsp} \p{Any}+\p{Xps} \p{Xwd}+\p{Any} \p{Any}+\p{Xuc}/BWZx
+
+/\p{L&}+\p{Any} \p{L&}+\p{L&} \P{L&}+\p{L&} \p{L&}+\p{L} \p{L&}+\p{Lu} \p{L&}+\p{Han} \p{L&}+\p{Xan} \p{L&}+\P{Xan} \p{L&}+\p{Xsp} \p{L&}+\p{Xps} \p{Xwd}+\p{L&} \p{L&}+\p{Xuc}/BWZx
+
+/\p{N}+\p{Any} \p{N}+\p{L&} \p{N}+\p{L} \p{N}+\P{L} \p{N}+\P{N} \p{N}+\p{Lu} \p{N}+\p{Han} \p{N}+\p{Xan} \p{N}+\p{Xsp} \p{N}+\p{Xps} \p{Xwd}+\p{N} \p{N}+\p{Xuc}/BWZx
+
+/\p{Lu}+\p{Any} \p{Lu}+\p{L&} \p{Lu}+\p{L} \p{Lu}+\p{Lu} \P{Lu}+\p{Lu} \p{Lu}+\p{Nd} \p{Lu}+\P{Nd} \p{Lu}+\p{Han} \p{Lu}+\p{Xan} \p{Lu}+\p{Xsp} \p{Lu}+\p{Xps} \p{Xwd}+\p{Lu} \p{Lu}+\p{Xuc}/BWZx
+
+/\p{Han}+\p{Lu} \p{Han}+\p{L&} \p{Han}+\p{L} \p{Han}+\p{Lu} \p{Han}+\p{Arabic} \p{Arabic}+\p{Arabic} \p{Han}+\p{Xan} \p{Han}+\p{Xsp} \p{Han}+\p{Xps} \p{Xwd}+\p{Han} \p{Han}+\p{Xuc}/BWZx
+
+/\p{Xan}+\p{Any} \p{Xan}+\p{L&} \P{Xan}+\p{L&} \p{Xan}+\p{L} \p{Xan}+\p{Lu} \p{Xan}+\p{Han} \p{Xan}+\p{Xan} \p{Xan}+\P{Xan} \p{Xan}+\p{Xsp} \p{Xan}+\p{Xps} \p{Xwd}+\p{Xan} \p{Xan}+\p{Xuc}/BWZx
+
+/\p{Xsp}+\p{Any} \p{Xsp}+\p{L&} \p{Xsp}+\p{L} \p{Xsp}+\p{Lu} \p{Xsp}+\p{Han} \p{Xsp}+\p{Xan} \p{Xsp}+\p{Xsp} \P{Xsp}+\p{Xsp} \p{Xsp}+\p{Xps} \p{Xwd}+\p{Xsp} \p{Xsp}+\p{Xuc}/BWZx
+
+/\p{Xwd}+\p{Any} \p{Xwd}+\p{L&} \p{Xwd}+\p{L} \p{Xwd}+\p{Lu} \p{Xwd}+\p{Han} \p{Xwd}+\p{Xan} \p{Xwd}+\p{Xsp} \p{Xwd}+\p{Xps} \p{Xwd}+\p{Xwd} \p{Xwd}+\P{Xwd} \p{Xwd}+\p{Xuc}/BWZx
+
+/\p{Xuc}+\p{Any} \p{Xuc}+\p{L&} \p{Xuc}+\p{L} \p{Xuc}+\p{Lu} \p{Xuc}+\p{Han} \p{Xuc}+\p{Xan} \p{Xuc}+\p{Xsp} \p{Xuc}+\p{Xps} \p{Xwd}+\p{Xuc} \p{Xuc}+\p{Xuc} \p{Xuc}+\P{Xuc}/BWZx
+
+/\p{N}+\p{Ll} \p{N}+\p{Nd} \p{N}+\P{Nd}/BWZx
+
+/\p{Xan}+\p{L} \p{Xan}+\p{N} \p{Xan}+\p{C} \p{Xan}+\P{L} \P{Xan}+\p{N} \p{Xan}+\P{C}/BWZx
+
+/\p{L}+\p{Xan} \p{N}+\p{Xan} \p{C}+\p{Xan} \P{L}+\p{Xan} \p{N}+\p{Xan} \P{C}+\p{Xan} \p{L}+\P{Xan}/BWZx
+
+/\p{Xan}+\p{Lu} \p{Xan}+\p{Nd} \p{Xan}+\p{Cc} \p{Xan}+\P{Ll} \P{Xan}+\p{No} \p{Xan}+\P{Cf}/BWZx
+
+/\p{Lu}+\p{Xan} \p{Nd}+\p{Xan} \p{Cs}+\p{Xan} \P{Lt}+\p{Xan} \p{Nl}+\p{Xan} \P{Cc}+\p{Xan} \p{Lt}+\P{Xan}/BWZx
+
+/\w+\p{P} \w+\p{Po} \w+\s \p{Xan}+\s \s+\p{Xan} \s+\w/BWZx
+
+/\w+\P{P} \W+\p{Po} \w+\S \P{Xan}+\s \s+\P{Xan} \s+\W/BWZx
+
+/\w+\p{Po} \w+\p{Pc} \W+\p{Po} \W+\p{Pc} \w+\P{Po} \w+\P{Pc}/BWZx
+
+/\p{Nl}+\p{Xan} \P{Nl}+\p{Xan} \p{Nl}+\P{Xan} \P{Nl}+\P{Xan}/BWZx
+
+/\p{Xan}+\p{Nl} \P{Xan}+\p{Nl} \p{Xan}+\P{Nl} \P{Xan}+\P{Nl}/BWZx
+
+/\p{Xan}+\p{Nd} \P{Xan}+\p{Nd} \p{Xan}+\P{Nd} \P{Xan}+\P{Nd}/BWZx
+
+/-- End auto-possessification tests --/
+
+/\w+/8CWBZ
+ abcd
+
+/[\p{N}]?+/BZO
+
+/[\p{L}ab]{2,3}+/BZO
+
+/\D+\X \d+\X \S+\X \s+\X \W+\X \w+\X \C+\X \R+\X \H+\X \h+\X \V+\X \v+\X a+\X \n+\X .+\X/BZx
+
+/.+\X/BZxs
+
+/\X+$/BZxm
+
+/\X+\D \X+\d \X+\S \X+\s \X+\W \X+\w \X+. \X+\C \X+\R \X+\H \X+\h \X+\V \X+\v \X+\X \X+\Z \X+\z \X+$/BZx
+
+/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/8WBZ
/-- End of testinput7 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput8 b/ext/pcre/pcrelib/testdata/testinput8
index e235445e01..bb2747b120 100644
--- a/ext/pcre/pcrelib/testdata/testinput8
+++ b/ext/pcre/pcrelib/testdata/testinput8
@@ -1,5 +1,8 @@
-/-- This set of tests check the DFA matching functionality of pcre_dfa_exec().
- The -dfa flag must be used with pcretest when running it. --/
+/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(),
+ excluding UTF and Unicode property support. The -dfa flag must be used with
+ pcretest when running it. --/
+
+< forbid 8W
/abc/
abc
@@ -16,7 +19,7 @@
ac
ab
-/a*/
+/a*/O
a
aaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -177,19 +180,19 @@
ayzq
axyzq
-/[^a]+/
+/[^a]+/O
bac
bcdefax
*** Failers
aaaaa
-/[^a]*/
+/[^a]*/O
bac
bcdefax
*** Failers
aaaaa
-/[^a]{3,5}/
+/[^a]{3,5}/O
xyz
awxyza
abcdefa
@@ -937,16 +940,16 @@
*** Failers
the abc
-/^[ab]{1,3}(ab*|b)/
+/^[ab]{1,3}(ab*|b)/O
aabbbbb
-/^[ab]{1,3}?(ab*|b)/
+/^[ab]{1,3}?(ab*|b)/O
aabbbbb
-/^[ab]{1,3}?(ab*?|b)/
+/^[ab]{1,3}?(ab*?|b)/O
aabbbbb
-/^[ab]{1,3}(ab*?|b)/
+/^[ab]{1,3}(ab*?|b)/O
aabbbbb
/ (?: [\040\t] | \(
@@ -1923,14 +1926,16 @@
abc\100\060
abc\100\60
-/abc\81/
- abc\081
- abc\0\x38\x31
-
-/abc\91/
- abc\091
- abc\0\x39\x31
-
+/^A\8B\9C$/
+ A8B9C
+ *** Failers
+ A\08B\09C
+
+/^[A\8B\9C]+$/
+ A8B9C
+ *** Failers
+ A8B9C\x00
+
/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/
abcdefghijk\12S
@@ -2049,13 +2054,13 @@
/foo(.*?)bar/
The food is under the bar in the barn.
-/(.*)(\d*)/
+/(.*)(\d*)/O
I have 2 numbers: 53147
/(.*)(\d+)/
I have 2 numbers: 53147
-/(.*?)(\d*)/
+/(.*?)(\d*)/O
I have 2 numbers: 53147
/(.*?)(\d+)/
@@ -3825,13 +3830,6 @@
/a*/g
abbab
-/^[a-\d]/
- abcde
- -things
- 0digit
- *** Failers
- bcdef
-
/^[\d-a]/
abcde
-things
@@ -4699,7 +4697,7 @@
/(?(R)a*(?1)|((?R))b)/
aaaabcde
-/(a+)/
+/(a+)/O
\O6aaaa
\O8aaaa
@@ -4798,4 +4796,39 @@
xxxxxxxxabcd
xx\xa0xxxxxabcd
+/abcd/
+ abcd\O0
+
+/-- These tests show up auto-possessification --/
+
+/[ab]*/
+ aaaa
+
+/[ab]*?/
+ aaaa
+
+/[ab]?/
+ aaaa
+
+/[ab]??/
+ aaaa
+
+/[ab]+/
+ aaaa
+
+/[ab]+?/
+ aaaa
+
+/[ab]{2,3}/
+ aaaa
+
+/[ab]{2,3}?/
+ aaaa
+
+/[ab]{2,}/
+ aaaa
+
+/[ab]{2,}?/
+ aaaa
+
/-- End of testinput8 --/
diff --git a/ext/pcre/pcrelib/testdata/testinput9 b/ext/pcre/pcrelib/testdata/testinput9
index 766c9c0fb6..4575ffe319 100644
--- a/ext/pcre/pcrelib/testdata/testinput9
+++ b/ext/pcre/pcrelib/testdata/testinput9
@@ -1,6 +1,8 @@
/-- This set of tests checks UTF-8 support with the DFA matching functionality
- of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running
- it. --/
+ of pcre_dfa_exec(), excluding Unicode property support. The -dfa flag must
+ be used with pcretest when running it. --/
+
+< forbid W
/\x{100}ab/8
\x{100}ab
@@ -239,16 +241,16 @@
/\x{100}{3,5}/8
abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX
-/\x{100}{3,}/8
+/\x{100}{3,}/8O
abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX
/(?<=a\x{100}{2}b)X/8
Xyyya\x{100}\x{100}bXzzz
-/\D*/8
+/\D*/8O
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-/\D*/8
+/\D*/8O
\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
/\D/8
@@ -584,16 +586,16 @@
a\n\n\n\rb
a\r
-/\h+\V?\v{3,4}/8
+/\h+\V?\v{3,4}/8O
\x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
-/\V?\v{3,4}/8
+/\V?\v{3,4}/8O
\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
-/\h+\V?\v{3,4}/8
+/\h+\V?\v{3,4}/8O
>\x09\x20\x{a0}X\x0a\x0a\x0a<
-/\V?\v{3,4}/8
+/\V?\v{3,4}/8O
>\x09\x20\x{a0}X\x0a\x0a\x0a<
/\H\h\V\v/8
@@ -602,7 +604,7 @@
** Failers
\x{a0} X\x0a
-/\H*\h+\V?\v{3,4}/8
+/\H*\h+\V?\v{3,4}/8O
\x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
\x09\x20\x{a0}\x0a\x0b\x0c\x0d\x0a
\x09\x20\x{a0}\x0a\x0b\x0c
@@ -615,7 +617,7 @@
** Failers
\x{2009} X\x0a
-/\H*\h+\V?\v{3,4}/8
+/\H*\h+\V?\v{3,4}/8O
\x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a
\x09\x{205f}\x{a0}\x0a\x{2029}\x0c\x{2028}\x0a
\x09\x20\x{202f}\x0a\x0b\x0c
diff --git a/ext/pcre/pcrelib/testdata/testinputEBC b/ext/pcre/pcrelib/testdata/testinputEBC
new file mode 100644
index 0000000000..56efcd00aa
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testinputEBC
@@ -0,0 +1,121 @@
+/-- This is a specialized test for checking, when PCRE is compiled with the
+EBCDIC option but in an ASCII environment, that newline and white space
+functionality is working. It catches cases where explicit values such as 0x0a
+have been used instead of names like CHAR_LF. Needless to say, it is not a
+genuine EBCDIC test! In patterns, alphabetic characters that follow a backslash
+must be in EBCDIC code. In data, newlines and other spacing characters must be
+in EBCDIC, but can be specified as escapes. --/
+
+/-- Test default newline and variations --/
+
+/^A/m
+ ABC
+ 12\x15ABC
+
+/^A/m<any>
+ 12\x15ABC
+ 12\x0dABC
+ 12\x0d\x15ABC
+ 12\x25ABC
+
+/^A/m<anycrlf>
+ 12\x15ABC
+ 12\x0dABC
+ 12\x0d\x15ABC
+ ** Fail
+ 12\x25ABC
+
+/-- Test \h --/
+
+/^A\/
+ A B
+
+/-- Test \H --/
+
+/^A\/
+ AB
+ ** Fail
+ A B
+
+/-- Test \R --/
+
+/^A\/
+ A\x15B
+ A\x0dB
+ A\x25B
+ A\x0bB
+ A\x0cB
+ ** Fail
+ A B
+
+/-- Test \v --/
+
+/^A\/
+ A\x15B
+ A\x0dB
+ A\x25B
+ A\x0bB
+ A\x0cB
+ ** Fail
+ A B
+
+/-- Test \V --/
+
+/^A\/
+ A B
+ ** Fail
+ A\x15B
+ A\x0dB
+ A\x25B
+ A\x0bB
+ A\x0cB
+
+/-- For repeated items, use an atomic group so that the output is the same
+for DFA matching (otherwise it may show multiple matches). --/
+
+/-- Test \h+ --/
+
+/^A(?>\+)/
+ A B
+
+/-- Test \H+ --/
+
+/^A(?>\+)/
+ AB
+ ** Fail
+ A B
+
+/-- Test \R+ --/
+
+/^A(?>\+)/
+ A\x15B
+ A\x0dB
+ A\x25B
+ A\x0bB
+ A\x0cB
+ ** Fail
+ A B
+
+/-- Test \v+ --/
+
+/^A(?>\+)/
+ A\x15B
+ A\x0dB
+ A\x25B
+ A\x0bB
+ A\x0cB
+ ** Fail
+ A B
+
+/-- Test \V+ --/
+
+/^A(?>\+)/
+ A B
+ ** Fail
+ A\x15B
+ A\x0dB
+ A\x25B
+ A\x0bB
+ A\x0cB
+
+/-- End --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput1 b/ext/pcre/pcrelib/testdata/testoutput1
index 8310e94618..4dafc0496a 100644
--- a/ext/pcre/pcrelib/testdata/testoutput1
+++ b/ext/pcre/pcrelib/testdata/testoutput1
@@ -1,6 +1,8 @@
/-- This set of tests is for features that are compatible with all versions of
- Perl >= 5.10, in non-UTF-8 mode. It should run clean for both the 8-bit and
- 16-bit PCRE libraries. --/
+ Perl >= 5.10, in non-UTF-8 mode. It should run clean for the 8-bit, 16-bit,
+ and 32-bit PCRE libraries. --/
+
+< forbid 89?=ABCDEFfGILMNPTUWXZ<
/the quick brown fox/
the quick brown fox
@@ -2149,18 +2151,35 @@ No match
abc\100\60
0: abc@0
1: abc
-
-/abc\81/
- abc\081
- 0: abc\x0081
- abc\0\x38\x31
- 0: abc\x0081
-
-/abc\91/
- abc\091
- 0: abc\x0091
- abc\0\x39\x31
- 0: abc\x0091
+
+/^A\8B\9C$/
+ A8B9C
+ 0: A8B9C
+ *** Failers
+No match
+ A\08B\09C
+No match
+
+/^(A)(B)(C)(D)(E)(F)(G)(H)(I)\8\9$/
+ ABCDEFGHIHI
+ 0: ABCDEFGHIHI
+ 1: A
+ 2: B
+ 3: C
+ 4: D
+ 5: E
+ 6: F
+ 7: G
+ 8: H
+ 9: I
+
+/^[A\8B\9C]+$/
+ A8B9C
+ 0: A8B9C
+ *** Failers
+No match
+ A8B9C\x00
+No match
/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\12\123/
abcdefghijkllS
@@ -5972,18 +5991,6 @@ No match
0:
0:
-/^[a-\d]/
- abcde
- 0: a
- -things
- 0: -
- 0digit
- 0: 0
- *** Failers
-No match
- bcdef
-No match
-
/^[\d-a]/
abcde
0: a
@@ -6006,15 +6013,15 @@ No match
/[\s]+/
> \x09\x0a\x0c\x0d\x0b<
- 0: \x09\x0a\x0c\x0d
+ 0: \x09\x0a\x0c\x0d\x0b
/\s+/
> \x09\x0a\x0c\x0d\x0b<
- 0: \x09\x0a\x0c\x0d
+ 0: \x09\x0a\x0c\x0d\x0b
/a b/x
ab
-No match
+ 0: ab
/(?!\A)x/m
a\nxb\n
@@ -6160,11 +6167,9 @@ No match
1: bc
2: bc
-/-- This tests for an IPv6 address in the form where it can have up to --/
-/-- eight components, one and only one of which is empty. This must be --/
-No match
-/-- an internal component. --/
-No match
+/-- This tests for an IPv6 address in the form where it can have up to
+ eight components, one and only one of which is empty. This must be
+ an internal component. --/
/^(?!:) # colon disallowed at start
(?: # start of item
@@ -6906,10 +6911,6 @@ No match
bc
0: b
-/^(?=(a)){0}b(?1)/
- backgammon
- 0: ba
-
/^(?=(?1))?[az]([abc])d/
abd
0: abd
@@ -7770,20 +7771,12 @@ No match
1: (ab(cd)ef)
2: ef
-/^(?!a(*SKIP)b)/
- ac
- 0:
-
/^(?=a(*SKIP)b|ac)/
** Failers
No match
ac
No match
-/^(?=a(*THEN)b|ac)/
- ac
- 0:
-
/^(?=a(*PRUNE)b)/
ab
0:
@@ -7796,10 +7789,6 @@ No match
ac
0:
-/^(?(?!a(*SKIP)b))/
- ac
- 0:
-
/(?>a\Kb)/
ab
0: b
@@ -8169,46 +8158,20 @@ No match
1: AB
2: B
-/\A.*?(?:a|b(*THEN)c)/
- ba
- 0: ba
-
-/\A.*?(?:a|bc)/
- ba
- 0: ba
-
-/\A.*?(a|b(*THEN)c)/
- ba
- 0: ba
- 1: a
-
/\A.*?(a|bc)/
ba
0: ba
1: a
-/\A.*?(?:a|b(*THEN)c)++/
- ba
- 0: ba
-
/\A.*?(?:a|bc)++/
ba
0: ba
-/\A.*?(a|b(*THEN)c)++/
- ba
- 0: ba
- 1: a
-
/\A.*?(a|bc)++/
ba
0: ba
1: a
-/\A.*?(?:a|b(*THEN)c|d)/
- ba
- 0: ba
-
/\A.*?(?:a|bc|d)/
ba
0: ba
@@ -8719,10 +8682,6 @@ No match
aac
0: aac
-/(?!a(*COMMIT)b)ac|cd/
- ac
- 0: ac
-
/((?:a?)*)*c/
aac
0: aac
@@ -8795,4 +8754,563 @@ No match
abcdfooxyz
0: foo
+/(?:(a(*PRUNE)b)){0}(?:(?1)|ac)/
+ ac
+ 0: ac
+
+/(?:(a(*SKIP)b)){0}(?:(?1)|ac)/
+ ac
+ 0: ac
+
+/(?<=(*SKIP)ac)a/
+ aa
+No match
+
+/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/xK
+ AAAC
+ 0: AC
+
+/a(*SKIP:m)x|ac(*:n)(*SKIP:n)d|ac/K
+ acacd
+ 0: acd
+MK: n
+
+/A(*SKIP:m)x|A(*SKIP:n)x|AB/K
+ AB
+ 0: AB
+
+/((*SKIP:r)d){0}a(*SKIP:m)x|ac(*:n)|ac/K
+ acacd
+ 0: ac
+MK: n
+
+/-- Tests that try to figure out how Perl works. My hypothesis is that the
+ first verb that is backtracked onto is the one that acts. This seems to be
+ the case almost all the time, but there is one exception that is perhaps a
+ bug. --/
+
+/-- This matches "aaaac"; each PRUNE advances one character until the subject
+ no longer starts with 5 'a's. --/
+
+/aaaaa(*PRUNE)b|a+c/
+ aaaaaac
+ 0: aaaac
+
+/-- Putting SKIP in front of PRUNE makes no difference, as it is never
+backtracked onto, whether or not it has a label. --/
+
+/aaaaa(*SKIP)(*PRUNE)b|a+c/
+ aaaaaac
+ 0: aaaac
+
+/aaaaa(*SKIP:N)(*PRUNE)b|a+c/
+ aaaaaac
+ 0: aaaac
+
+/aaaa(*:N)a(*SKIP:N)(*PRUNE)b|a+c/
+ aaaaaac
+ 0: aaaac
+
+/-- Putting THEN in front makes no difference. */
+
+/aaaaa(*THEN)(*PRUNE)b|a+c/
+ aaaaaac
+ 0: aaaac
+
+/-- However, putting COMMIT in front of the prune changes it to "no match". I
+ think this is inconsistent and possibly a bug. For the moment, running this
+ test is moved out of the Perl-compatible file. --/
+
+/aaaaa(*COMMIT)(*PRUNE)b|a+c/
+
+
+/---- OK, lets play the same game again using SKIP instead of PRUNE. ----/
+
+/-- This matches "ac" because SKIP forces the next match to start on the
+ sixth "a". --/
+
+/aaaaa(*SKIP)b|a+c/
+ aaaaaac
+ 0: ac
+
+/-- Putting PRUNE in front makes no difference. --/
+
+/aaaaa(*PRUNE)(*SKIP)b|a+c/
+ aaaaaac
+ 0: ac
+
+/-- Putting THEN in front makes no difference. --/
+
+/aaaaa(*THEN)(*SKIP)b|a+c/
+ aaaaaac
+ 0: ac
+
+/-- In this case, neither does COMMIT. This still matches "ac". --/
+
+/aaaaa(*COMMIT)(*SKIP)b|a+c/
+ aaaaaac
+ 0: ac
+
+/-- This gives "no match", as expected. --/
+
+/aaaaa(*COMMIT)b|a+c/
+ aaaaaac
+No match
+
+
+/------ Tests using THEN ------/
+
+/-- This matches "aaaaaac", as expected. --/
+
+/aaaaa(*THEN)b|a+c/
+ aaaaaac
+ 0: aaaaaac
+
+/-- Putting SKIP in front makes no difference. --/
+
+/aaaaa(*SKIP)(*THEN)b|a+c/
+ aaaaaac
+ 0: aaaaaac
+
+/-- Putting PRUNE in front makes no difference. --/
+
+/aaaaa(*PRUNE)(*THEN)b|a+c/
+ aaaaaac
+ 0: aaaaaac
+
+/-- Putting COMMIT in front makes no difference. --/
+
+/aaaaa(*COMMIT)(*THEN)b|a+c/
+ aaaaaac
+ 0: aaaaaac
+
+/-- End of "priority" tests --/
+
+/aaaaa(*:m)(*PRUNE:m)(*SKIP:m)m|a+/
+ aaaaaa
+ 0: a
+
+/aaaaa(*:m)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+/
+ aaaaaa
+ 0: a
+
+/aaaaa(*:n)(*PRUNE:m)(*SKIP:m)m|a+/
+ aaaaaa
+ 0: aaaa
+
+/aaaaa(*:n)(*MARK:m)(*PRUNE)(*SKIP:m)m|a+/
+ aaaaaa
+ 0: a
+
+/a(*MARK:A)aa(*PRUNE:A)a(*SKIP:A)b|a+c/
+ aaaac
+ 0: aac
+
+/a(*MARK:A)aa(*MARK:A)a(*SKIP:A)b|a+c/
+ aaaac
+ 0: ac
+
+/aaa(*PRUNE:A)a(*SKIP:A)b|a+c/
+ aaaac
+ 0: aac
+
+/aaa(*MARK:A)a(*SKIP:A)b|a+c/
+ aaaac
+ 0: ac
+
+/a(*:m)a(*COMMIT)(*SKIP:m)b|a+c/K
+ aaaaaac
+ 0: ac
+
+/.?(a|b(*THEN)c)/
+ ba
+ 0: ba
+ 1: a
+
+/(a(*COMMIT)b)c|abd/
+ abc
+ 0: abc
+ 1: ab
+ abd
+No match
+
+/(?=a(*COMMIT)b)abc|abd/
+ abc
+ 0: abc
+ abd
+ 0: abd
+
+/(?>a(*COMMIT)b)c|abd/
+ abc
+ 0: abc
+ abd
+ 0: abd
+
+/a(?=b(*COMMIT)c)[^d]|abd/
+ abd
+No match
+ abc
+ 0: ab
+
+/a(?=bc).|abd/
+ abd
+ 0: abd
+ abc
+ 0: ab
+
+/a(?>b(*COMMIT)c)d|abd/
+ abceabd
+No match
+
+/a(?>bc)d|abd/
+ abceabd
+ 0: abd
+
+/(?>a(*COMMIT)b)c|abd/
+ abd
+ 0: abd
+
+/(?>a(*COMMIT)c)d|abd/
+ abd
+No match
+
+/((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/
+ ac
+ 0: ac
+ 1: <unset>
+ 2: c
+
+/-- These tests were formerly in test 2, but changes in PCRE and Perl have
+ made them compatible. --/
+
+/^(a)?(?(1)a|b)+$/
+ *** Failers
+No match
+ a
+No match
+
+/(?=a\Kb)ab/
+ ab
+ 0: b
+
+/(?!a\Kb)ac/
+ ac
+ 0: ac
+
+/^abc(?<=b\Kc)d/
+ abcd
+ 0: cd
+
+/^abc(?<!b\Kq)d/
+ abcd
+ 0: abcd
+
+
+/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK
+ AAAC
+No match, mark = A
+
+/^((abc|abcx)(*THEN)y|abcd)/
+ abcd
+ 0: abcd
+ 1: abcd
+ *** Failers
+No match
+ abcxy
+No match
+
+/^((yes|no)(*THEN)(*F))?/
+ yes
+No match
+
+/(A (.*) C? (*THEN) | A D) (*FAIL)/x
+AbcdCBefgBhiBqz
+No match
+
+/(A (.*) C? (*THEN) | A D) z/x
+AbcdCBefgBhiBqz
+No match
+
+/(A (.*) C? (*THEN) | A D) \s* (*FAIL)/x
+AbcdCBefgBhiBqz
+No match
+
+/(A (.*) C? (*THEN) | A D) \s* z/x
+AbcdCBefgBhiBqz
+No match
+
+/(A (.*) (?:C|) (*THEN) | A D) (*FAIL)/x
+AbcdCBefgBhiBqz
+No match
+
+/(A (.*) (?:C|) (*THEN) | A D) z/x
+AbcdCBefgBhiBqz
+No match
+
+/(A (.*) C{0,6} (*THEN) | A D) (*FAIL)/x
+AbcdCBefgBhiBqz
+No match
+
+/(A (.*) C{0,6} (*THEN) | A D) z/x
+AbcdCBefgBhiBqz
+No match
+
+/(A (.*) (CE){0,6} (*THEN) | A D) (*FAIL)/x
+AbcdCEBefgBhiBqz
+No match
+
+/(A (.*) (CE){0,6} (*THEN) | A D) z/x
+AbcdCEBefgBhiBqz
+No match
+
+/(A (.*) (CE*){0,6} (*THEN) | A D) (*FAIL)/x
+AbcdCBefgBhiBqz
+No match
+
+/(A (.*) (CE*){0,6} (*THEN) | A D) z/x
+AbcdCBefgBhiBqz
+No match
+
+/(?=a(*COMMIT)b|ac)ac|ac/
+ ac
+No match
+
+/(?=a(*COMMIT)b|(ac)) ac | (a)c/x
+ ac
+No match
+
+/--------/
+
+/(?(?!b(*THEN)a)bn|bnn)/
+ bnn
+ 0: bn
+
+/(?!b(*SKIP)a)bn|bnn/
+ bnn
+ 0: bn
+
+/(?(?!b(*SKIP)a)bn|bnn)/
+ bnn
+ 0: bn
+
+/(?!b(*PRUNE)a)bn|bnn/
+ bnn
+ 0: bn
+
+/(?(?!b(*PRUNE)a)bn|bnn)/
+ bnn
+ 0: bn
+
+/(?!b(*COMMIT)a)bn|bnn/
+ bnn
+ 0: bn
+
+/(?(?!b(*COMMIT)a)bn|bnn)/
+ bnn
+ 0: bn
+
+/(?=b(*SKIP)a)bn|bnn/
+ bnn
+No match
+
+/(?=b(*THEN)a)bn|bnn/
+ bnn
+ 0: bnn
+
+ /^(?!a(*SKIP)b)/
+ ac
+ 0:
+
+ /^(?!a(*SKIP)b)../
+ acd
+ 0: ac
+
+/(?!a(*SKIP)b)../
+ acd
+ 0: ac
+
+/^(?(?!a(*SKIP)b))/
+ ac
+ 0:
+
+/^(?!a(*PRUNE)b)../
+ acd
+ 0: ac
+
+/(?!a(*PRUNE)b)../
+ acd
+ 0: ac
+
+ /(?!a(*COMMIT)b)ac|cd/
+ ac
+ 0: ac
+
+/\A.*?(?:a|bc)/
+ ba
+ 0: ba
+
+/^(A(*THEN)B|C(*THEN)D)/
+ CD
+ 0: CD
+ 1: CD
+
+/(*:m(m)(?&y)(?(DEFINE)(?<y>b))/K
+ abc
+ 0: b
+MK: m(m
+
+/(*PRUNE:m(m)(?&y)(?(DEFINE)(?<y>b))/K
+ abc
+ 0: b
+MK: m(m
+
+/(*SKIP:m(m)(?&y)(?(DEFINE)(?<y>b))/K
+ abc
+ 0: b
+
+/(*THEN:m(m)(?&y)(?(DEFINE)(?<y>b))/K
+ abc
+ 0: b
+MK: m(m
+
+/^\d*\w{4}/
+ 1234
+ 0: 1234
+ 123
+No match
+
+/^[^b]*\w{4}/
+ aaaa
+ 0: aaaa
+ aaa
+No match
+
+/^[^b]*\w{4}/i
+ aaaa
+ 0: aaaa
+ aaa
+No match
+
+/^a*\w{4}/
+ aaaa
+ 0: aaaa
+ aaa
+No match
+
+/^a*\w{4}/i
+ aaaa
+ 0: aaaa
+ aaa
+No match
+
+/(?(?=ab)ab)/+
+ ca
+ 0:
+ 0+ ca
+ cd
+ 0:
+ 0+ cd
+
+/(?:(?<n>foo)|(?<n>bar))\k<n>/J
+ foofoo
+ 0: foofoo
+ 1: foo
+ barbar
+ 0: barbar
+ 1: <unset>
+ 2: bar
+
+/(?<n>A)(?:(?<n>foo)|(?<n>bar))\k<n>/J
+ AfooA
+ 0: AfooA
+ 1: A
+ 2: foo
+ AbarA
+ 0: AbarA
+ 1: A
+ 2: <unset>
+ 3: bar
+ ** Failers
+No match
+ Afoofoo
+No match
+ Abarbar
+No match
+
+/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/
+ 1 IN SOA non-sp1 non-sp2(
+ 0: 1 IN SOA non-sp1 non-sp2(
+ 1: 1
+ 2: non-sp1
+ 3: non-sp2
+
+/^ (?:(?<A>A)|(?'B'B)(?<A>A)) (?('A')x) (?(<B>)y)$/xJ
+ Ax
+ 0: Ax
+ 1: A
+ BAxy
+ 0: BAxy
+ 1: <unset>
+ 2: B
+ 3: A
+
+/^A\xZ/
+ A\0Z
+ 0: A\x00Z
+
+/^A\o{123}B/
+ A\123B
+ 0: ASB
+
+/ ^ a + + b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ a + #comment
+ + b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ a + #comment
+ #comment
+ + b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ (?> a + ) b $ /x
+ aaaab
+ 0: aaaab
+
+/ ^ ( a + ) + + \w $ /x
+ aaaab
+ 0: aaaab
+ 1: aaaa
+
+/(?:a\Kb)*+/+
+ ababc
+ 0: b
+ 0+ c
+
+/(?>a\Kb)*/+
+ ababc
+ 0: b
+ 0+ c
+
+/(?:a\Kb)*/+
+ ababc
+ 0: b
+ 0+ c
+
+/(a\Kb)*+/+
+ ababc
+ 0: b
+ 0+ c
+ 1: ab
+
+/(a\Kb)*/+
+ ababc
+ 0: b
+ 0+ c
+ 1: ab
+
/-- End of testinput1 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput10 b/ext/pcre/pcrelib/testdata/testoutput10
index 049d446314..b89169cdd3 100644
--- a/ext/pcre/pcrelib/testdata/testoutput10
+++ b/ext/pcre/pcrelib/testdata/testoutput10
@@ -39,9 +39,6 @@ No match
/^\pL+/8
abcd
0: abcd
- 1: abc
- 2: ab
- 3: a
a
0: a
*** Failers
@@ -50,45 +47,24 @@ No match
/^\PL+/8
1234
0: 1234
- 1: 123
- 2: 12
- 3: 1
=
0: =
*** Failers
0: ***
- 1: ***
- 2: **
- 3: *
abcd
No match
/^\X+/8
abcdA\x{300}\x{301}\x{302}
0: abcdA\x{300}\x{301}\x{302}
- 1: abcd
- 2: abc
- 3: ab
- 4: a
A\x{300}\x{301}\x{302}
0: A\x{300}\x{301}\x{302}
A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}
0: A\x{300}\x{301}\x{302}A\x{300}\x{301}\x{302}
- 1: A\x{300}\x{301}\x{302}
a
0: a
*** Failers
0: *** Failers
- 1: *** Failer
- 2: *** Faile
- 3: *** Fail
- 4: *** Fai
- 5: *** Fa
- 6: *** F
- 7: ***
- 8: ***
- 9: **
-10: *
\x{300}\x{301}\x{302}
0: \x{300}\x{301}\x{302}
@@ -255,6 +231,18 @@ No match
/^\p{Cf}/8
\x{601}
0: \x{601}
+ \x{180e}
+ 0: \x{180e}
+ \x{061c}
+ 0: \x{61c}
+ \x{2066}
+ 0: \x{2066}
+ \x{2067}
+ 0: \x{2067}
+ \x{2068}
+ 0: \x{2068}
+ \x{2069}
+ 0: \x{2069}
** Failers
No match
\x{09f}
@@ -353,6 +341,8 @@ No match
/^\p{Mn}/8
\x{300}
0: \x{300}
+ \x{1a1b}
+ 0: \x{1a1b}
** Failers
No match
X
@@ -360,7 +350,7 @@ No match
\x{903}
No match
-/^\p{Nd}+/8
+/^\p{Nd}+/8O
0123456789\x{660}\x{661}\x{662}\x{663}\x{664}\x{665}\x{666}\x{667}\x{668}\x{669}\x{66a}
0: 0123456789\x{660}\x{661}\x{662}\x{663}\x{664}\x{665}\x{666}\x{667}\x{668}\x{669}
1: 0123456789\x{660}\x{661}\x{662}\x{663}\x{664}\x{665}\x{666}\x{667}\x{668}
@@ -466,6 +456,10 @@ No match
0: }
\x{f3b}
0: \x{f3b}
+ \x{2309}
+ 0: \x{2309}
+ \x{230b}
+ 0: \x{230b}
** Failers
No match
X
@@ -480,7 +474,7 @@ No match
No match
\x{f3c}
No match
-
+
/^\p{Pf}/8
\x{bb}
0: \x{bb}
@@ -526,6 +520,10 @@ No match
0: {
\x{f3c}
0: \x{f3c}
+ \x{2308}
+ 0: \x{2308}
+ \x{230a}
+ 0: \x{230a}
** Failers
No match
X
@@ -542,10 +540,6 @@ No match
/^\p{Sc}+/8
$\x{a2}\x{a3}\x{a4}\x{a5}\x{a6}
0: $\x{a2}\x{a3}\x{a4}\x{a5}
- 1: $\x{a2}\x{a3}\x{a4}
- 2: $\x{a2}\x{a3}
- 3: $\x{a2}
- 4: $
\x{9f2}
0: \x{9f2}
** Failers
@@ -568,11 +562,6 @@ No match
/^\p{Sm}+/8
+<|~\x{ac}\x{2044}
0: +<|~\x{ac}\x{2044}
- 1: +<|~\x{ac}
- 2: +<|~
- 3: +<|
- 4: +<
- 5: +
** Failers
No match
X
@@ -619,8 +608,6 @@ No match
0: \x{a0}
\x{1680}
0: \x{1680}
- \x{180e}
- 0: \x{180e}
\x{2000}
0: \x{2000}
\x{2001}
@@ -767,23 +754,10 @@ No match
/[\p{Nd}+-]+/8
1234
0: 1234
- 1: 123
- 2: 12
- 3: 1
12-34
0: 12-34
- 1: 12-3
- 2: 12-
- 3: 12
- 4: 1
12+\x{661}-34
0: 12+\x{661}-34
- 1: 12+\x{661}-3
- 2: 12+\x{661}-
- 3: 12+\x{661}
- 4: 12+
- 5: 12
- 6: 1
** Failers
No match
abcd
@@ -792,28 +766,16 @@ No match
/[\P{Nd}]+/8
abcd
0: abcd
- 1: abc
- 2: ab
- 3: a
** Failers
0: ** Failers
- 1: ** Failer
- 2: ** Faile
- 3: ** Fail
- 4: ** Fai
- 5: ** Fa
- 6: ** F
- 7: **
- 8: **
- 9: *
1234
No match
-/\D+/8
+/\D+/8O
11111111111111111111111111111111111111111111111111111111111111111111111
No match
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-Matched, but too many subsidiary matches
+Matched, but offsets vector is too small to show all matches
0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -837,11 +799,11 @@ Matched, but too many subsidiary matches
20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-/\P{Nd}+/8
+/\P{Nd}+/8O
11111111111111111111111111111111111111111111111111111111111111111111111
No match
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-Matched, but too many subsidiary matches
+Matched, but offsets vector is too small to show all matches
0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -865,11 +827,11 @@ Matched, but too many subsidiary matches
20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-/[\D]+/8
+/[\D]+/8O
11111111111111111111111111111111111111111111111111111111111111111111111
No match
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-Matched, but too many subsidiary matches
+Matched, but offsets vector is too small to show all matches
0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -893,11 +855,11 @@ Matched, but too many subsidiary matches
20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-/[\P{Nd}]+/8
+/[\P{Nd}]+/8O
11111111111111111111111111111111111111111111111111111111111111111111111
No match
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-Matched, but too many subsidiary matches
+Matched, but offsets vector is too small to show all matches
0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -921,11 +883,11 @@ Matched, but too many subsidiary matches
20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-/[\D\P{Nd}]+/8
+/[\D\P{Nd}]+/8O
11111111111111111111111111111111111111111111111111111111111111111111111
No match
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-Matched, but too many subsidiary matches
+Matched, but offsets vector is too small to show all matches
0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -1046,10 +1008,6 @@ No match
/\x{391}+/8i
\x{391}\x{3b1}\x{3b1}\x{3b1}\x{391}
0: \x{391}\x{3b1}\x{3b1}\x{3b1}\x{391}
- 1: \x{391}\x{3b1}\x{3b1}\x{3b1}
- 2: \x{391}\x{3b1}\x{3b1}
- 3: \x{391}\x{3b1}
- 4: \x{391}
/\x{391}{3,5}(.)/8i
\x{391}\x{3b1}\x{3b1}\x{3b1}\x{391}X
@@ -1236,8 +1194,6 @@ No match
/^\p{Han}+/8
\x{2e81}\x{3007}\x{2f804}\x{31a0}
0: \x{2e81}\x{3007}\x{2f804}
- 1: \x{2e81}\x{3007}
- 2: \x{2e81}
** Failers
No match
\x{2e7f}
@@ -1248,15 +1204,6 @@ No match
0: \x{3105}
** Failers
0: ** Failers
- 1: ** Failer
- 2: ** Faile
- 3: ** Fail
- 4: ** Fai
- 5: ** Fa
- 6: ** F
- 7: **
- 8: **
- 9: *
\x{30ff}
No match
@@ -1469,12 +1416,8 @@ No match
/^\p{Any}{3,5}/8
abcdefgh
0: abcde
- 1: abcd
- 2: abc
\x{1234}\n\r\x{3456}xyz
0: \x{1234}\x{0a}\x{0d}\x{3456}x
- 1: \x{1234}\x{0a}\x{0d}\x{3456}
- 2: \x{1234}\x{0a}\x{0d}
/^\P{Any}{3,5}?/8
** Failers
@@ -1639,14 +1582,10 @@ No match
/\x{c0}+\x{116}+/8i
\x{c0}\x{e0}\x{116}\x{117}
0: \x{c0}\x{e0}\x{116}\x{117}
- 1: \x{c0}\x{e0}\x{116}
/[\x{c0}\x{116}]+/8i
\x{c0}\x{e0}\x{116}\x{117}
0: \x{c0}\x{e0}\x{116}\x{117}
- 1: \x{c0}\x{e0}\x{116}
- 2: \x{c0}\x{e0}
- 3: \x{c0}
/Check property support in non-UTF-8 mode/
@@ -1693,16 +1632,6 @@ No match
/^\p{Xan}+/8
ABCD1234\x{6ca}\x{a6c}\x{10a7}_
0: ABCD1234\x{6ca}\x{a6c}\x{10a7}
- 1: ABCD1234\x{6ca}\x{a6c}
- 2: ABCD1234\x{6ca}
- 3: ABCD1234
- 4: ABCD123
- 5: ABCD12
- 6: ABCD1
- 7: ABCD
- 8: ABC
- 9: AB
-10: A
** Failers
No match
_ABC
@@ -1711,28 +1640,10 @@ No match
/^\p{Xan}*/8
ABCD1234\x{6ca}\x{a6c}\x{10a7}_
0: ABCD1234\x{6ca}\x{a6c}\x{10a7}
- 1: ABCD1234\x{6ca}\x{a6c}
- 2: ABCD1234\x{6ca}
- 3: ABCD1234
- 4: ABCD123
- 5: ABCD12
- 6: ABCD1
- 7: ABCD
- 8: ABC
- 9: AB
-10: A
-11:
/^\p{Xan}{2,9}/8
ABCD1234\x{6ca}\x{a6c}\x{10a7}_
0: ABCD1234\x{6ca}
- 1: ABCD1234
- 2: ABCD123
- 3: ABCD12
- 4: ABCD1
- 5: ABCD
- 6: ABC
- 7: AB
/^[\p{Xan}]/8
ABCD1234_
@@ -1753,16 +1664,6 @@ No match
/^[\p{Xan}]+/8
ABCD1234\x{6ca}\x{a6c}\x{10a7}_
0: ABCD1234\x{6ca}\x{a6c}\x{10a7}
- 1: ABCD1234\x{6ca}\x{a6c}
- 2: ABCD1234\x{6ca}
- 3: ABCD1234
- 4: ABCD123
- 5: ABCD12
- 6: ABCD1
- 7: ABCD
- 8: ABC
- 9: AB
-10: A
** Failers
No match
_ABC
@@ -1776,53 +1677,57 @@ No match
\x{0b}
No match
-/^>\p{Xsp}+/8
+/^>\p{Xsp}+/8O
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
- 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
- 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
- 3: > \x{09}\x{0a}\x{0c}\x{0d}
- 4: > \x{09}\x{0a}\x{0c}
- 5: > \x{09}\x{0a}
- 6: > \x{09}
- 7: >
-
-/^>\p{Xsp}*/8
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
+ 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
+ 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
+ 4: > \x{09}\x{0a}\x{0c}\x{0d}
+ 5: > \x{09}\x{0a}\x{0c}
+ 6: > \x{09}\x{0a}
+ 7: > \x{09}
+ 8: >
+
+/^>\p{Xsp}*/8O
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
- 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
- 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
- 3: > \x{09}\x{0a}\x{0c}\x{0d}
- 4: > \x{09}\x{0a}\x{0c}
- 5: > \x{09}\x{0a}
- 6: > \x{09}
- 7: >
- 8: >
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
+ 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
+ 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
+ 4: > \x{09}\x{0a}\x{0c}\x{0d}
+ 5: > \x{09}\x{0a}\x{0c}
+ 6: > \x{09}\x{0a}
+ 7: > \x{09}
+ 8: >
+ 9: >
-/^>\p{Xsp}{2,9}/8
+/^>\p{Xsp}{2,9}/8O
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
- 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
- 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
- 3: > \x{09}\x{0a}\x{0c}\x{0d}
- 4: > \x{09}\x{0a}\x{0c}
- 5: > \x{09}\x{0a}
- 6: > \x{09}
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
+ 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
+ 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
+ 4: > \x{09}\x{0a}\x{0c}\x{0d}
+ 5: > \x{09}\x{0a}\x{0c}
+ 6: > \x{09}\x{0a}
+ 7: > \x{09}
-/^>[\p{Xsp}]/8
+/^>[\p{Xsp}]/8O
>\x{2028}\x{0b}
0: >\x{2028}
-/^>[\p{Xsp}]+/8
+/^>[\p{Xsp}]+/8O
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
- 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
- 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
- 3: > \x{09}\x{0a}\x{0c}\x{0d}
- 4: > \x{09}\x{0a}\x{0c}
- 5: > \x{09}\x{0a}
- 6: > \x{09}
- 7: >
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
+ 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
+ 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
+ 4: > \x{09}\x{0a}\x{0c}\x{0d}
+ 5: > \x{09}\x{0a}\x{0c}
+ 6: > \x{09}\x{0a}
+ 7: > \x{09}
+ 8: >
/^>\p{Xps}/8
>\x{1680}\x{2028}\x{0b}
@@ -1837,14 +1742,6 @@ No match
/^>\p{Xps}+/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
- 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
- 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
- 4: > \x{09}\x{0a}\x{0c}\x{0d}
- 5: > \x{09}\x{0a}\x{0c}
- 6: > \x{09}\x{0a}
- 7: > \x{09}
- 8: >
/^>\p{Xps}+?/8
>\x{1680}\x{2028}\x{0b}
@@ -1855,26 +1752,10 @@ No match
/^>\p{Xps}*/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
- 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
- 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
- 4: > \x{09}\x{0a}\x{0c}\x{0d}
- 5: > \x{09}\x{0a}\x{0c}
- 6: > \x{09}\x{0a}
- 7: > \x{09}
- 8: >
- 9: >
/^>\p{Xps}{2,9}/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
- 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
- 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
- 4: > \x{09}\x{0a}\x{0c}\x{0d}
- 5: > \x{09}\x{0a}\x{0c}
- 6: > \x{09}\x{0a}
- 7: > \x{09}
/^>\p{Xps}{2,9}?/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
@@ -1894,14 +1775,6 @@ No match
/^>[\p{Xps}]+/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 1: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
- 2: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}
- 3: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}
- 4: > \x{09}\x{0a}\x{0c}\x{0d}
- 5: > \x{09}\x{0a}\x{0c}
- 6: > \x{09}\x{0a}
- 7: > \x{09}
- 8: >
/^\p{Xwd}/8
ABCD
@@ -1924,42 +1797,14 @@ No match
/^\p{Xwd}+/8
ABCD1234\x{6ca}\x{a6c}\x{10a7}_
0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_
- 1: ABCD1234\x{6ca}\x{a6c}\x{10a7}
- 2: ABCD1234\x{6ca}\x{a6c}
- 3: ABCD1234\x{6ca}
- 4: ABCD1234
- 5: ABCD123
- 6: ABCD12
- 7: ABCD1
- 8: ABCD
- 9: ABC
-10: AB
-11: A
/^\p{Xwd}*/8
ABCD1234\x{6ca}\x{a6c}\x{10a7}_
0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_
- 1: ABCD1234\x{6ca}\x{a6c}\x{10a7}
- 2: ABCD1234\x{6ca}\x{a6c}
- 3: ABCD1234\x{6ca}
- 4: ABCD1234
- 5: ABCD123
- 6: ABCD12
- 7: ABCD1
- 8: ABCD
- 9: ABC
-10: AB
-11: A
-12:
/^\p{Xwd}{2,9}/8
A_12\x{6ca}\x{a6c}\x{10a7}
0: A_12\x{6ca}\x{a6c}\x{10a7}
- 1: A_12\x{6ca}\x{a6c}
- 2: A_12\x{6ca}
- 3: A_12
- 4: A_1
- 5: A_
/^[\p{Xwd}]/8
ABCD1234_
@@ -1982,17 +1827,6 @@ No match
/^[\p{Xwd}]+/8
ABCD1234\x{6ca}\x{a6c}\x{10a7}_
0: ABCD1234\x{6ca}\x{a6c}\x{10a7}_
- 1: ABCD1234\x{6ca}\x{a6c}\x{10a7}
- 2: ABCD1234\x{6ca}\x{a6c}
- 3: ABCD1234\x{6ca}
- 4: ABCD1234
- 5: ABCD123
- 6: ABCD12
- 7: ABCD1
- 8: ABCD
- 9: ABC
-10: AB
-11: A
/-- Unicode properties for \b abd \B --/
@@ -2043,7 +1877,6 @@ No match
/[^\x{100}]+/8i
\x{100}\x{101}XX
0: XX
- 1: X
/^\X/8
A\P
@@ -2090,7 +1923,6 @@ Partial match: A\x{300}\x{301}A\x{300}\x{301}
/^\X+/8
AA\P
0: AA
- 1: A
AA\P\P
Partial match: AA
@@ -2271,435 +2103,299 @@ Partial match: AA
/\x{1e9e}+/8i
\x{1e9e}\x{00df}
0: \x{1e9e}\x{df}
- 1: \x{1e9e}
/[z\x{1e9e}]+/8i
\x{1e9e}\x{00df}
0: \x{1e9e}\x{df}
- 1: \x{1e9e}
/\x{00df}+/8i
\x{1e9e}\x{00df}
0: \x{1e9e}\x{df}
- 1: \x{1e9e}
/[z\x{00df}]+/8i
\x{1e9e}\x{00df}
0: \x{1e9e}\x{df}
- 1: \x{1e9e}
/\x{1f88}+/8i
\x{1f88}\x{1f80}
0: \x{1f88}\x{1f80}
- 1: \x{1f88}
/[z\x{1f88}]+/8i
\x{1f88}\x{1f80}
0: \x{1f88}\x{1f80}
- 1: \x{1f88}
/-- Perl matches these --/
/\x{00b5}+/8i
\x{00b5}\x{039c}\x{03bc}
0: \x{b5}\x{39c}\x{3bc}
- 1: \x{b5}\x{39c}
- 2: \x{b5}
/\x{039c}+/8i
\x{00b5}\x{039c}\x{03bc}
0: \x{b5}\x{39c}\x{3bc}
- 1: \x{b5}\x{39c}
- 2: \x{b5}
/\x{03bc}+/8i
\x{00b5}\x{039c}\x{03bc}
0: \x{b5}\x{39c}\x{3bc}
- 1: \x{b5}\x{39c}
- 2: \x{b5}
/\x{00c5}+/8i
\x{00c5}\x{00e5}\x{212b}
0: \x{c5}\x{e5}\x{212b}
- 1: \x{c5}\x{e5}
- 2: \x{c5}
/\x{00e5}+/8i
\x{00c5}\x{00e5}\x{212b}
0: \x{c5}\x{e5}\x{212b}
- 1: \x{c5}\x{e5}
- 2: \x{c5}
/\x{212b}+/8i
\x{00c5}\x{00e5}\x{212b}
0: \x{c5}\x{e5}\x{212b}
- 1: \x{c5}\x{e5}
- 2: \x{c5}
/\x{01c4}+/8i
\x{01c4}\x{01c5}\x{01c6}
0: \x{1c4}\x{1c5}\x{1c6}
- 1: \x{1c4}\x{1c5}
- 2: \x{1c4}
/\x{01c5}+/8i
\x{01c4}\x{01c5}\x{01c6}
0: \x{1c4}\x{1c5}\x{1c6}
- 1: \x{1c4}\x{1c5}
- 2: \x{1c4}
/\x{01c6}+/8i
\x{01c4}\x{01c5}\x{01c6}
0: \x{1c4}\x{1c5}\x{1c6}
- 1: \x{1c4}\x{1c5}
- 2: \x{1c4}
/\x{01c7}+/8i
\x{01c7}\x{01c8}\x{01c9}
0: \x{1c7}\x{1c8}\x{1c9}
- 1: \x{1c7}\x{1c8}
- 2: \x{1c7}
/\x{01c8}+/8i
\x{01c7}\x{01c8}\x{01c9}
0: \x{1c7}\x{1c8}\x{1c9}
- 1: \x{1c7}\x{1c8}
- 2: \x{1c7}
/\x{01c9}+/8i
\x{01c7}\x{01c8}\x{01c9}
0: \x{1c7}\x{1c8}\x{1c9}
- 1: \x{1c7}\x{1c8}
- 2: \x{1c7}
/\x{01ca}+/8i
\x{01ca}\x{01cb}\x{01cc}
0: \x{1ca}\x{1cb}\x{1cc}
- 1: \x{1ca}\x{1cb}
- 2: \x{1ca}
/\x{01cb}+/8i
\x{01ca}\x{01cb}\x{01cc}
0: \x{1ca}\x{1cb}\x{1cc}
- 1: \x{1ca}\x{1cb}
- 2: \x{1ca}
/\x{01cc}+/8i
\x{01ca}\x{01cb}\x{01cc}
0: \x{1ca}\x{1cb}\x{1cc}
- 1: \x{1ca}\x{1cb}
- 2: \x{1ca}
/\x{01f1}+/8i
\x{01f1}\x{01f2}\x{01f3}
0: \x{1f1}\x{1f2}\x{1f3}
- 1: \x{1f1}\x{1f2}
- 2: \x{1f1}
/\x{01f2}+/8i
\x{01f1}\x{01f2}\x{01f3}
0: \x{1f1}\x{1f2}\x{1f3}
- 1: \x{1f1}\x{1f2}
- 2: \x{1f1}
/\x{01f3}+/8i
\x{01f1}\x{01f2}\x{01f3}
0: \x{1f1}\x{1f2}\x{1f3}
- 1: \x{1f1}\x{1f2}
- 2: \x{1f1}
/\x{0345}+/8i
\x{0345}\x{0399}\x{03b9}\x{1fbe}
0: \x{345}\x{399}\x{3b9}\x{1fbe}
- 1: \x{345}\x{399}\x{3b9}
- 2: \x{345}\x{399}
- 3: \x{345}
/\x{0399}+/8i
\x{0345}\x{0399}\x{03b9}\x{1fbe}
0: \x{345}\x{399}\x{3b9}\x{1fbe}
- 1: \x{345}\x{399}\x{3b9}
- 2: \x{345}\x{399}
- 3: \x{345}
/\x{03b9}+/8i
\x{0345}\x{0399}\x{03b9}\x{1fbe}
0: \x{345}\x{399}\x{3b9}\x{1fbe}
- 1: \x{345}\x{399}\x{3b9}
- 2: \x{345}\x{399}
- 3: \x{345}
/\x{1fbe}+/8i
\x{0345}\x{0399}\x{03b9}\x{1fbe}
0: \x{345}\x{399}\x{3b9}\x{1fbe}
- 1: \x{345}\x{399}\x{3b9}
- 2: \x{345}\x{399}
- 3: \x{345}
/\x{0392}+/8i
\x{0392}\x{03b2}\x{03d0}
0: \x{392}\x{3b2}\x{3d0}
- 1: \x{392}\x{3b2}
- 2: \x{392}
/\x{03b2}+/8i
\x{0392}\x{03b2}\x{03d0}
0: \x{392}\x{3b2}\x{3d0}
- 1: \x{392}\x{3b2}
- 2: \x{392}
/\x{03d0}+/8i
\x{0392}\x{03b2}\x{03d0}
0: \x{392}\x{3b2}\x{3d0}
- 1: \x{392}\x{3b2}
- 2: \x{392}
/\x{0395}+/8i
\x{0395}\x{03b5}\x{03f5}
0: \x{395}\x{3b5}\x{3f5}
- 1: \x{395}\x{3b5}
- 2: \x{395}
/\x{03b5}+/8i
\x{0395}\x{03b5}\x{03f5}
0: \x{395}\x{3b5}\x{3f5}
- 1: \x{395}\x{3b5}
- 2: \x{395}
/\x{03f5}+/8i
\x{0395}\x{03b5}\x{03f5}
0: \x{395}\x{3b5}\x{3f5}
- 1: \x{395}\x{3b5}
- 2: \x{395}
/\x{0398}+/8i
\x{0398}\x{03b8}\x{03d1}\x{03f4}
0: \x{398}\x{3b8}\x{3d1}\x{3f4}
- 1: \x{398}\x{3b8}\x{3d1}
- 2: \x{398}\x{3b8}
- 3: \x{398}
/\x{03b8}+/8i
\x{0398}\x{03b8}\x{03d1}\x{03f4}
0: \x{398}\x{3b8}\x{3d1}\x{3f4}
- 1: \x{398}\x{3b8}\x{3d1}
- 2: \x{398}\x{3b8}
- 3: \x{398}
/\x{03d1}+/8i
\x{0398}\x{03b8}\x{03d1}\x{03f4}
0: \x{398}\x{3b8}\x{3d1}\x{3f4}
- 1: \x{398}\x{3b8}\x{3d1}
- 2: \x{398}\x{3b8}
- 3: \x{398}
/\x{03f4}+/8i
\x{0398}\x{03b8}\x{03d1}\x{03f4}
0: \x{398}\x{3b8}\x{3d1}\x{3f4}
- 1: \x{398}\x{3b8}\x{3d1}
- 2: \x{398}\x{3b8}
- 3: \x{398}
/\x{039a}+/8i
\x{039a}\x{03ba}\x{03f0}
0: \x{39a}\x{3ba}\x{3f0}
- 1: \x{39a}\x{3ba}
- 2: \x{39a}
/\x{03ba}+/8i
\x{039a}\x{03ba}\x{03f0}
0: \x{39a}\x{3ba}\x{3f0}
- 1: \x{39a}\x{3ba}
- 2: \x{39a}
/\x{03f0}+/8i
\x{039a}\x{03ba}\x{03f0}
0: \x{39a}\x{3ba}\x{3f0}
- 1: \x{39a}\x{3ba}
- 2: \x{39a}
/\x{03a0}+/8i
\x{03a0}\x{03c0}\x{03d6}
0: \x{3a0}\x{3c0}\x{3d6}
- 1: \x{3a0}\x{3c0}
- 2: \x{3a0}
/\x{03c0}+/8i
\x{03a0}\x{03c0}\x{03d6}
0: \x{3a0}\x{3c0}\x{3d6}
- 1: \x{3a0}\x{3c0}
- 2: \x{3a0}
/\x{03d6}+/8i
\x{03a0}\x{03c0}\x{03d6}
0: \x{3a0}\x{3c0}\x{3d6}
- 1: \x{3a0}\x{3c0}
- 2: \x{3a0}
/\x{03a1}+/8i
\x{03a1}\x{03c1}\x{03f1}
0: \x{3a1}\x{3c1}\x{3f1}
- 1: \x{3a1}\x{3c1}
- 2: \x{3a1}
/\x{03c1}+/8i
\x{03a1}\x{03c1}\x{03f1}
0: \x{3a1}\x{3c1}\x{3f1}
- 1: \x{3a1}\x{3c1}
- 2: \x{3a1}
/\x{03f1}+/8i
\x{03a1}\x{03c1}\x{03f1}
0: \x{3a1}\x{3c1}\x{3f1}
- 1: \x{3a1}\x{3c1}
- 2: \x{3a1}
/\x{03a3}+/8i
\x{03A3}\x{03C2}\x{03C3}
0: \x{3a3}\x{3c2}\x{3c3}
- 1: \x{3a3}\x{3c2}
- 2: \x{3a3}
/\x{03c2}+/8i
\x{03A3}\x{03C2}\x{03C3}
0: \x{3a3}\x{3c2}\x{3c3}
- 1: \x{3a3}\x{3c2}
- 2: \x{3a3}
/\x{03c3}+/8i
\x{03A3}\x{03C2}\x{03C3}
0: \x{3a3}\x{3c2}\x{3c3}
- 1: \x{3a3}\x{3c2}
- 2: \x{3a3}
/\x{03a6}+/8i
\x{03a6}\x{03c6}\x{03d5}
0: \x{3a6}\x{3c6}\x{3d5}
- 1: \x{3a6}\x{3c6}
- 2: \x{3a6}
/\x{03c6}+/8i
\x{03a6}\x{03c6}\x{03d5}
0: \x{3a6}\x{3c6}\x{3d5}
- 1: \x{3a6}\x{3c6}
- 2: \x{3a6}
/\x{03d5}+/8i
\x{03a6}\x{03c6}\x{03d5}
0: \x{3a6}\x{3c6}\x{3d5}
- 1: \x{3a6}\x{3c6}
- 2: \x{3a6}
/\x{03c9}+/8i
\x{03c9}\x{03a9}\x{2126}
0: \x{3c9}\x{3a9}\x{2126}
- 1: \x{3c9}\x{3a9}
- 2: \x{3c9}
/\x{03a9}+/8i
\x{03c9}\x{03a9}\x{2126}
0: \x{3c9}\x{3a9}\x{2126}
- 1: \x{3c9}\x{3a9}
- 2: \x{3c9}
/\x{2126}+/8i
\x{03c9}\x{03a9}\x{2126}
0: \x{3c9}\x{3a9}\x{2126}
- 1: \x{3c9}\x{3a9}
- 2: \x{3c9}
/\x{1e60}+/8i
\x{1e60}\x{1e61}\x{1e9b}
0: \x{1e60}\x{1e61}\x{1e9b}
- 1: \x{1e60}\x{1e61}
- 2: \x{1e60}
/\x{1e61}+/8i
\x{1e60}\x{1e61}\x{1e9b}
0: \x{1e60}\x{1e61}\x{1e9b}
- 1: \x{1e60}\x{1e61}
- 2: \x{1e60}
/\x{1e9b}+/8i
\x{1e60}\x{1e61}\x{1e9b}
0: \x{1e60}\x{1e61}\x{1e9b}
- 1: \x{1e60}\x{1e61}
- 2: \x{1e60}
/\x{1e9e}+/8i
\x{1e9e}\x{00df}
0: \x{1e9e}\x{df}
- 1: \x{1e9e}
/\x{00df}+/8i
\x{1e9e}\x{00df}
0: \x{1e9e}\x{df}
- 1: \x{1e9e}
/\x{1f88}+/8i
\x{1f88}\x{1f80}
0: \x{1f88}\x{1f80}
- 1: \x{1f88}
/\x{1f80}+/8i
\x{1f88}\x{1f80}
0: \x{1f88}\x{1f80}
- 1: \x{1f88}
/\x{004b}+/8i
\x{004b}\x{006b}\x{212a}
0: Kk\x{212a}
- 1: Kk
- 2: K
/\x{006b}+/8i
\x{004b}\x{006b}\x{212a}
0: Kk\x{212a}
- 1: Kk
- 2: K
/\x{212a}+/8i
\x{004b}\x{006b}\x{212a}
0: Kk\x{212a}
- 1: Kk
- 2: K
/\x{0053}+/8i
\x{0053}\x{0073}\x{017f}
0: Ss\x{17f}
- 1: Ss
- 2: S
/\x{0073}+/8i
\x{0053}\x{0073}\x{017f}
0: Ss\x{17f}
- 1: Ss
- 2: S
/\x{017f}+/8i
\x{0053}\x{0073}\x{017f}
0: Ss\x{17f}
- 1: Ss
- 2: S
/ist/8i
ikt
@@ -2723,4 +2419,129 @@ No match
iskt
No match
+/^\p{Xuc}/8
+ $abc
+ 0: $
+ @abc
+ 0: @
+ `abc
+ 0: `
+ \x{1234}abc
+ 0: \x{1234}
+ ** Failers
+No match
+ abc
+No match
+
+/^\p{Xuc}+/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}\x{e000}
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\p{Xuc}+?/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}\x{e000}
+ 1: $@`\x{a0}\x{1234}
+ 2: $@`\x{a0}
+ 3: $@`
+ 4: $@
+ 5: $
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\p{Xuc}+?\*/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}\x{e000}*
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\p{Xuc}++/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}\x{e000}
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\p{Xuc}{3,5}/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\p{Xuc}{3,5}?/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}
+ 1: $@`\x{a0}
+ 2: $@`
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^[\p{Xuc}]/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^[\p{Xuc}]+/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}\x{e000}
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\P{Xuc}/8
+ abc
+ 0: a
+ ** Failers
+ 0: *
+ $abc
+No match
+ @abc
+No match
+ `abc
+No match
+ \x{1234}abc
+No match
+
+/^[\P{Xuc}]/8
+ abc
+ 0: a
+ ** Failers
+ 0: *
+ $abc
+No match
+ @abc
+No match
+ `abc
+No match
+ \x{1234}abc
+No match
+
+/^A\s+Z/8W
+ A\x{2005}Z
+ 0: A\x{2005}Z
+ A\x{85}\x{180e}\x{2005}Z
+ 0: A\x{85}\x{180e}\x{2005}Z
+
+/^A[\s]+Z/8W
+ A\x{2005}Z
+ 0: A\x{2005}Z
+ A\x{85}\x{180e}\x{2005}Z
+ 0: A\x{85}\x{180e}\x{2005}Z
+
/-- End of testinput10 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput11-16 b/ext/pcre/pcrelib/testdata/testoutput11-16
new file mode 100644
index 0000000000..f1ad8887b4
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput11-16
@@ -0,0 +1,712 @@
+/-- These are a few representative patterns whose lengths and offsets are to be
+shown when the link size is 2. This is just a doublecheck test to ensure the
+sizes don't go horribly wrong when something is changed. The pattern contents
+are all themselves checked in other tests. Unicode, including property support,
+is required for these tests. --/
+
+/((?i)b)/BM
+Memory allocation (code space): 24
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 5 CBra 1
+ 5 /i b
+ 7 5 Ket
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/(?s)(.*X|^B)/BM
+Memory allocation (code space): 38
+------------------------------------------------------------------
+ 0 16 Bra
+ 2 7 CBra 1
+ 5 AllAny*
+ 7 X
+ 9 5 Alt
+ 11 ^
+ 12 B
+ 14 12 Ket
+ 16 16 Ket
+ 18 End
+------------------------------------------------------------------
+
+/(?s:.*X|^B)/BM
+Memory allocation (code space): 36
+------------------------------------------------------------------
+ 0 15 Bra
+ 2 6 Bra
+ 4 AllAny*
+ 6 X
+ 8 5 Alt
+ 10 ^
+ 11 B
+ 13 11 Ket
+ 15 15 Ket
+ 17 End
+------------------------------------------------------------------
+
+/^[[:alnum:]]/BM
+Memory allocation (code space): 46
+------------------------------------------------------------------
+ 0 20 Bra
+ 2 ^
+ 3 [0-9A-Za-z]
+ 20 20 Ket
+ 22 End
+------------------------------------------------------------------
+
+/#/IxMD
+Memory allocation (code space): 10
+------------------------------------------------------------------
+ 0 2 Bra
+ 2 2 Ket
+ 4 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+May match empty string
+Options: extended
+No first char
+No need char
+
+/a#/IxMD
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 a
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: extended
+First char = 'a'
+No need char
+
+/x?+/BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 x?+
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/x++/BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 x++
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/x{1,3}+/BM
+Memory allocation (code space): 20
+------------------------------------------------------------------
+ 0 7 Bra
+ 2 x
+ 4 x{0,2}+
+ 7 7 Ket
+ 9 End
+------------------------------------------------------------------
+
+/(x)*+/BM
+Memory allocation (code space): 26
+------------------------------------------------------------------
+ 0 10 Bra
+ 2 Braposzero
+ 3 5 CBraPos 1
+ 6 x
+ 8 5 KetRpos
+ 10 10 Ket
+ 12 End
+------------------------------------------------------------------
+
+/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM
+Memory allocation (code space): 142
+------------------------------------------------------------------
+ 0 68 Bra
+ 2 ^
+ 3 63 CBra 1
+ 6 5 CBra 2
+ 9 a+
+ 11 5 Ket
+ 13 21 CBra 3
+ 16 [ab]+?
+ 34 21 Ket
+ 36 21 CBra 4
+ 39 [bc]+
+ 57 21 Ket
+ 59 5 CBra 5
+ 62 \w*+
+ 64 5 Ket
+ 66 63 Ket
+ 68 68 Ket
+ 70 End
+------------------------------------------------------------------
+
+|8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM
+Memory allocation (code space): 1648
+------------------------------------------------------------------
+ 0 821 Bra
+ 2 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
+820 \b
+821 821 Ket
+823 End
+------------------------------------------------------------------
+
+|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM
+Memory allocation (code space): 1628
+------------------------------------------------------------------
+ 0 811 Bra
+ 2 $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
+810 \b
+811 811 Ket
+813 End
+------------------------------------------------------------------
+
+/(a(?1)b)/BM
+Memory allocation (code space): 32
+------------------------------------------------------------------
+ 0 13 Bra
+ 2 9 CBra 1
+ 5 a
+ 7 2 Recurse
+ 9 b
+ 11 9 Ket
+ 13 13 Ket
+ 15 End
+------------------------------------------------------------------
+
+/(a(?1)+b)/BM
+Memory allocation (code space): 40
+------------------------------------------------------------------
+ 0 17 Bra
+ 2 13 CBra 1
+ 5 a
+ 7 4 Once
+ 9 2 Recurse
+ 11 4 KetRmax
+ 13 b
+ 15 13 Ket
+ 17 17 Ket
+ 19 End
+------------------------------------------------------------------
+
+/a(?P<name1>b|c)d(?P<longername2>e)/BM
+Memory allocation (code space): 80
+------------------------------------------------------------------
+ 0 24 Bra
+ 2 a
+ 4 5 CBra 1
+ 7 b
+ 9 4 Alt
+ 11 c
+ 13 9 Ket
+ 15 d
+ 17 5 CBra 2
+ 20 e
+ 22 5 Ket
+ 24 24 Ket
+ 26 End
+------------------------------------------------------------------
+
+/(?:a(?P<c>c(?P<d>d)))(?P<a>a)/BM
+Memory allocation (code space): 73
+------------------------------------------------------------------
+ 0 29 Bra
+ 2 18 Bra
+ 4 a
+ 6 12 CBra 1
+ 9 c
+ 11 5 CBra 2
+ 14 d
+ 16 5 Ket
+ 18 12 Ket
+ 20 18 Ket
+ 22 5 CBra 3
+ 25 a
+ 27 5 Ket
+ 29 29 Ket
+ 31 End
+------------------------------------------------------------------
+
+/(?P<a>a)...(?P=a)bbb(?P>a)d/BM
+Memory allocation (code space): 57
+------------------------------------------------------------------
+ 0 24 Bra
+ 2 5 CBra 1
+ 5 a
+ 7 5 Ket
+ 9 Any
+ 10 Any
+ 11 Any
+ 12 \1
+ 14 bbb
+ 20 2 Recurse
+ 22 d
+ 24 24 Ket
+ 26 End
+------------------------------------------------------------------
+
+/abc(?C255)de(?C)f/BM
+Memory allocation (code space): 50
+------------------------------------------------------------------
+ 0 22 Bra
+ 2 abc
+ 8 Callout 255 10 1
+ 12 de
+ 16 Callout 0 16 1
+ 20 f
+ 22 22 Ket
+ 24 End
+------------------------------------------------------------------
+
+/abcde/CBM
+Memory allocation (code space): 78
+------------------------------------------------------------------
+ 0 36 Bra
+ 2 Callout 255 0 1
+ 6 a
+ 8 Callout 255 1 1
+ 12 b
+ 14 Callout 255 2 1
+ 18 c
+ 20 Callout 255 3 1
+ 24 d
+ 26 Callout 255 4 1
+ 30 e
+ 32 Callout 255 5 0
+ 36 36 Ket
+ 38 End
+------------------------------------------------------------------
+
+/\x{100}/8BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{100}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\x{1000}/8BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{1000}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\x{10000}/8BM
+Memory allocation (code space): 16
+------------------------------------------------------------------
+ 0 5 Bra
+ 2 \x{10000}
+ 5 5 Ket
+ 7 End
+------------------------------------------------------------------
+
+/\x{100000}/8BM
+Memory allocation (code space): 16
+------------------------------------------------------------------
+ 0 5 Bra
+ 2 \x{100000}
+ 5 5 Ket
+ 7 End
+------------------------------------------------------------------
+
+/\x{10ffff}/8BM
+Memory allocation (code space): 16
+------------------------------------------------------------------
+ 0 5 Bra
+ 2 \x{10ffff}
+ 5 5 Ket
+ 7 End
+------------------------------------------------------------------
+
+/\x{110000}/8BM
+Failed: character value in \x{} or \o{} is too large at offset 9
+
+/[\x{ff}]/8BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{ff}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[\x{100}]/8BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{100}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\x80/8BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x80
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\xff/8BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{ff}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\x{0041}\x{2262}\x{0391}\x{002e}/D8M
+Memory allocation (code space): 26
+------------------------------------------------------------------
+ 0 10 Bra
+ 2 A\x{2262}\x{391}.
+ 10 10 Ket
+ 12 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'A'
+Need char = '.'
+
+/\x{D55c}\x{ad6d}\x{C5B4}/D8M
+Memory allocation (code space): 22
+------------------------------------------------------------------
+ 0 8 Bra
+ 2 \x{d55c}\x{ad6d}\x{c5b4}
+ 8 8 Ket
+ 10 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{d55c}
+Need char = \x{c5b4}
+
+/\x{65e5}\x{672c}\x{8a9e}/D8M
+Memory allocation (code space): 22
+------------------------------------------------------------------
+ 0 8 Bra
+ 2 \x{65e5}\x{672c}\x{8a9e}
+ 8 8 Ket
+ 10 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{65e5}
+Need char = \x{8a9e}
+
+/[\x{100}]/8BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{100}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[Z\x{100}]/8BM
+Memory allocation (code space): 54
+------------------------------------------------------------------
+ 0 24 Bra
+ 2 [Z\x{100}]
+ 24 24 Ket
+ 26 End
+------------------------------------------------------------------
+
+/^[\x{100}\E-\Q\E\x{150}]/B8M
+Memory allocation (code space): 26
+------------------------------------------------------------------
+ 0 10 Bra
+ 2 ^
+ 3 [\x{100}-\x{150}]
+ 10 10 Ket
+ 12 End
+------------------------------------------------------------------
+
+/^[\QĀ\E-\QŐ\E]/B8M
+Memory allocation (code space): 26
+------------------------------------------------------------------
+ 0 10 Bra
+ 2 ^
+ 3 [\x{100}-\x{150}]
+ 10 10 Ket
+ 12 End
+------------------------------------------------------------------
+
+/^[\QĀ\E-\QŐ\E/B8M
+Failed: missing terminating ] for character class at offset 13
+
+/[\p{L}]/BM
+Memory allocation (code space): 24
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\p{L}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[\p{^L}]/BM
+Memory allocation (code space): 24
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\P{L}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[\P{L}]/BM
+Memory allocation (code space): 24
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\P{L}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[\P{^L}]/BM
+Memory allocation (code space): 24
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\p{L}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[abc\p{L}\x{0660}]/8BM
+Memory allocation (code space): 60
+------------------------------------------------------------------
+ 0 27 Bra
+ 2 [a-c\p{L}\x{660}]
+ 27 27 Ket
+ 29 End
+------------------------------------------------------------------
+
+/[\p{Nd}]/8BM
+Memory allocation (code space): 24
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\p{Nd}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[\p{Nd}+-]+/8BM
+Memory allocation (code space): 58
+------------------------------------------------------------------
+ 0 26 Bra
+ 2 [+\-\p{Nd}]++
+ 26 26 Ket
+ 28 End
+------------------------------------------------------------------
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM
+Memory allocation (code space): 32
+------------------------------------------------------------------
+ 0 13 Bra
+ 2 /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
+ 13 13 Ket
+ 15 End
+------------------------------------------------------------------
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM
+Memory allocation (code space): 32
+------------------------------------------------------------------
+ 0 13 Bra
+ 2 A\x{391}\x{10427}\x{ff3a}\x{1fb0}
+ 13 13 Ket
+ 15 End
+------------------------------------------------------------------
+
+/[\x{105}-\x{109}]/8iBM
+Memory allocation (code space): 24
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\x{104}-\x{109}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/( ( (?(1)0|) )* )/xBM
+Memory allocation (code space): 52
+------------------------------------------------------------------
+ 0 23 Bra
+ 2 19 CBra 1
+ 5 Brazero
+ 6 13 SCBra 2
+ 9 6 Cond
+ 11 1 Cond ref
+ 13 0
+ 15 2 Alt
+ 17 8 Ket
+ 19 13 KetRmax
+ 21 19 Ket
+ 23 23 Ket
+ 25 End
+------------------------------------------------------------------
+
+/( (?(1)0|)* )/xBM
+Memory allocation (code space): 42
+------------------------------------------------------------------
+ 0 18 Bra
+ 2 14 CBra 1
+ 5 Brazero
+ 6 6 SCond
+ 8 1 Cond ref
+ 10 0
+ 12 2 Alt
+ 14 8 KetRmax
+ 16 14 Ket
+ 18 18 Ket
+ 20 End
+------------------------------------------------------------------
+
+/[a]/BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 a
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[a]/8BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 a
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[\xaa]/BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{aa}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[\xaa]/8BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{aa}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[^a]/BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 [^a]
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[^a]/8BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 [^a]
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[^\xaa]/BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 [^\x{aa}]
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[^\xaa]/8BM
+Memory allocation (code space): 14
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 [^\x{aa}]
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[^\d]/8WB
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [^\p{Nd}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[[:^alpha:][:^cntrl:]]+/8WB
+------------------------------------------------------------------
+ 0 26 Bra
+ 2 [ -~\x80-\xff\P{L}]++
+ 26 26 Ket
+ 28 End
+------------------------------------------------------------------
+
+/[[:^cntrl:][:^alpha:]]+/8WB
+------------------------------------------------------------------
+ 0 26 Bra
+ 2 [ -~\x80-\xff\P{L}]++
+ 26 26 Ket
+ 28 End
+------------------------------------------------------------------
+
+/[[:alpha:]]+/8WB
+------------------------------------------------------------------
+ 0 10 Bra
+ 2 [\p{L}]++
+ 10 10 Ket
+ 12 End
+------------------------------------------------------------------
+
+/[[:^alpha:]\S]+/8WB
+------------------------------------------------------------------
+ 0 13 Bra
+ 2 [\P{L}\P{Xsp}]++
+ 13 13 Ket
+ 15 End
+------------------------------------------------------------------
+
+/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B
+------------------------------------------------------------------
+ 0 60 Bra
+ 2 abc
+ 8 5 CBra 1
+ 11 d
+ 13 4 Alt
+ 15 e
+ 17 9 Ket
+ 19 *THEN
+ 20 x
+ 22 12 CBra 2
+ 25 123
+ 31 *THEN
+ 32 4
+ 34 24 Alt
+ 36 567
+ 42 5 CBra 3
+ 45 b
+ 47 4 Alt
+ 49 q
+ 51 9 Ket
+ 53 *THEN
+ 54 xx
+ 58 36 Ket
+ 60 60 Ket
+ 62 End
+------------------------------------------------------------------
+
+/-- End of testinput11 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput11-32 b/ext/pcre/pcrelib/testdata/testoutput11-32
new file mode 100644
index 0000000000..266e55d067
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput11-32
@@ -0,0 +1,712 @@
+/-- These are a few representative patterns whose lengths and offsets are to be
+shown when the link size is 2. This is just a doublecheck test to ensure the
+sizes don't go horribly wrong when something is changed. The pattern contents
+are all themselves checked in other tests. Unicode, including property support,
+is required for these tests. --/
+
+/((?i)b)/BM
+Memory allocation (code space): 48
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 5 CBra 1
+ 5 /i b
+ 7 5 Ket
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/(?s)(.*X|^B)/BM
+Memory allocation (code space): 76
+------------------------------------------------------------------
+ 0 16 Bra
+ 2 7 CBra 1
+ 5 AllAny*
+ 7 X
+ 9 5 Alt
+ 11 ^
+ 12 B
+ 14 12 Ket
+ 16 16 Ket
+ 18 End
+------------------------------------------------------------------
+
+/(?s:.*X|^B)/BM
+Memory allocation (code space): 72
+------------------------------------------------------------------
+ 0 15 Bra
+ 2 6 Bra
+ 4 AllAny*
+ 6 X
+ 8 5 Alt
+ 10 ^
+ 11 B
+ 13 11 Ket
+ 15 15 Ket
+ 17 End
+------------------------------------------------------------------
+
+/^[[:alnum:]]/BM
+Memory allocation (code space): 60
+------------------------------------------------------------------
+ 0 12 Bra
+ 2 ^
+ 3 [0-9A-Za-z]
+ 12 12 Ket
+ 14 End
+------------------------------------------------------------------
+
+/#/IxMD
+Memory allocation (code space): 20
+------------------------------------------------------------------
+ 0 2 Bra
+ 2 2 Ket
+ 4 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+May match empty string
+Options: extended
+No first char
+No need char
+
+/a#/IxMD
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 a
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: extended
+First char = 'a'
+No need char
+
+/x?+/BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 x?+
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/x++/BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 x++
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/x{1,3}+/BM
+Memory allocation (code space): 40
+------------------------------------------------------------------
+ 0 7 Bra
+ 2 x
+ 4 x{0,2}+
+ 7 7 Ket
+ 9 End
+------------------------------------------------------------------
+
+/(x)*+/BM
+Memory allocation (code space): 52
+------------------------------------------------------------------
+ 0 10 Bra
+ 2 Braposzero
+ 3 5 CBraPos 1
+ 6 x
+ 8 5 KetRpos
+ 10 10 Ket
+ 12 End
+------------------------------------------------------------------
+
+/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM
+Memory allocation (code space): 220
+------------------------------------------------------------------
+ 0 52 Bra
+ 2 ^
+ 3 47 CBra 1
+ 6 5 CBra 2
+ 9 a+
+ 11 5 Ket
+ 13 13 CBra 3
+ 16 [ab]+?
+ 26 13 Ket
+ 28 13 CBra 4
+ 31 [bc]+
+ 41 13 Ket
+ 43 5 CBra 5
+ 46 \w*+
+ 48 5 Ket
+ 50 47 Ket
+ 52 52 Ket
+ 54 End
+------------------------------------------------------------------
+
+|8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM
+Memory allocation (code space): 3296
+------------------------------------------------------------------
+ 0 821 Bra
+ 2 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
+820 \b
+821 821 Ket
+823 End
+------------------------------------------------------------------
+
+|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM
+Memory allocation (code space): 3256
+------------------------------------------------------------------
+ 0 811 Bra
+ 2 $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
+810 \b
+811 811 Ket
+813 End
+------------------------------------------------------------------
+
+/(a(?1)b)/BM
+Memory allocation (code space): 64
+------------------------------------------------------------------
+ 0 13 Bra
+ 2 9 CBra 1
+ 5 a
+ 7 2 Recurse
+ 9 b
+ 11 9 Ket
+ 13 13 Ket
+ 15 End
+------------------------------------------------------------------
+
+/(a(?1)+b)/BM
+Memory allocation (code space): 80
+------------------------------------------------------------------
+ 0 17 Bra
+ 2 13 CBra 1
+ 5 a
+ 7 4 Once
+ 9 2 Recurse
+ 11 4 KetRmax
+ 13 b
+ 15 13 Ket
+ 17 17 Ket
+ 19 End
+------------------------------------------------------------------
+
+/a(?P<name1>b|c)d(?P<longername2>e)/BM
+Memory allocation (code space): 186
+------------------------------------------------------------------
+ 0 24 Bra
+ 2 a
+ 4 5 CBra 1
+ 7 b
+ 9 4 Alt
+ 11 c
+ 13 9 Ket
+ 15 d
+ 17 5 CBra 2
+ 20 e
+ 22 5 Ket
+ 24 24 Ket
+ 26 End
+------------------------------------------------------------------
+
+/(?:a(?P<c>c(?P<d>d)))(?P<a>a)/BM
+Memory allocation (code space): 155
+------------------------------------------------------------------
+ 0 29 Bra
+ 2 18 Bra
+ 4 a
+ 6 12 CBra 1
+ 9 c
+ 11 5 CBra 2
+ 14 d
+ 16 5 Ket
+ 18 12 Ket
+ 20 18 Ket
+ 22 5 CBra 3
+ 25 a
+ 27 5 Ket
+ 29 29 Ket
+ 31 End
+------------------------------------------------------------------
+
+/(?P<a>a)...(?P=a)bbb(?P>a)d/BM
+Memory allocation (code space): 117
+------------------------------------------------------------------
+ 0 24 Bra
+ 2 5 CBra 1
+ 5 a
+ 7 5 Ket
+ 9 Any
+ 10 Any
+ 11 Any
+ 12 \1
+ 14 bbb
+ 20 2 Recurse
+ 22 d
+ 24 24 Ket
+ 26 End
+------------------------------------------------------------------
+
+/abc(?C255)de(?C)f/BM
+Memory allocation (code space): 100
+------------------------------------------------------------------
+ 0 22 Bra
+ 2 abc
+ 8 Callout 255 10 1
+ 12 de
+ 16 Callout 0 16 1
+ 20 f
+ 22 22 Ket
+ 24 End
+------------------------------------------------------------------
+
+/abcde/CBM
+Memory allocation (code space): 156
+------------------------------------------------------------------
+ 0 36 Bra
+ 2 Callout 255 0 1
+ 6 a
+ 8 Callout 255 1 1
+ 12 b
+ 14 Callout 255 2 1
+ 18 c
+ 20 Callout 255 3 1
+ 24 d
+ 26 Callout 255 4 1
+ 30 e
+ 32 Callout 255 5 0
+ 36 36 Ket
+ 38 End
+------------------------------------------------------------------
+
+/\x{100}/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{100}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\x{1000}/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{1000}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\x{10000}/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{10000}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\x{100000}/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{100000}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\x{10ffff}/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{10ffff}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\x{110000}/8BM
+Failed: character value in \x{} or \o{} is too large at offset 9
+
+/[\x{ff}]/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{ff}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[\x{100}]/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{100}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\x80/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x80
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\xff/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{ff}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/\x{0041}\x{2262}\x{0391}\x{002e}/D8M
+Memory allocation (code space): 52
+------------------------------------------------------------------
+ 0 10 Bra
+ 2 A\x{2262}\x{391}.
+ 10 10 Ket
+ 12 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'A'
+Need char = '.'
+
+/\x{D55c}\x{ad6d}\x{C5B4}/D8M
+Memory allocation (code space): 44
+------------------------------------------------------------------
+ 0 8 Bra
+ 2 \x{d55c}\x{ad6d}\x{c5b4}
+ 8 8 Ket
+ 10 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{d55c}
+Need char = \x{c5b4}
+
+/\x{65e5}\x{672c}\x{8a9e}/D8M
+Memory allocation (code space): 44
+------------------------------------------------------------------
+ 0 8 Bra
+ 2 \x{65e5}\x{672c}\x{8a9e}
+ 8 8 Ket
+ 10 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{65e5}
+Need char = \x{8a9e}
+
+/[\x{100}]/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{100}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[Z\x{100}]/8BM
+Memory allocation (code space): 76
+------------------------------------------------------------------
+ 0 16 Bra
+ 2 [Z\x{100}]
+ 16 16 Ket
+ 18 End
+------------------------------------------------------------------
+
+/^[\x{100}\E-\Q\E\x{150}]/B8M
+Memory allocation (code space): 52
+------------------------------------------------------------------
+ 0 10 Bra
+ 2 ^
+ 3 [\x{100}-\x{150}]
+ 10 10 Ket
+ 12 End
+------------------------------------------------------------------
+
+/^[\QĀ\E-\QŐ\E]/B8M
+Memory allocation (code space): 52
+------------------------------------------------------------------
+ 0 10 Bra
+ 2 ^
+ 3 [\x{100}-\x{150}]
+ 10 10 Ket
+ 12 End
+------------------------------------------------------------------
+
+/^[\QĀ\E-\QŐ\E/B8M
+Failed: missing terminating ] for character class at offset 13
+
+/[\p{L}]/BM
+Memory allocation (code space): 48
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\p{L}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[\p{^L}]/BM
+Memory allocation (code space): 48
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\P{L}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[\P{L}]/BM
+Memory allocation (code space): 48
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\P{L}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[\P{^L}]/BM
+Memory allocation (code space): 48
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\p{L}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[abc\p{L}\x{0660}]/8BM
+Memory allocation (code space): 88
+------------------------------------------------------------------
+ 0 19 Bra
+ 2 [a-c\p{L}\x{660}]
+ 19 19 Ket
+ 21 End
+------------------------------------------------------------------
+
+/[\p{Nd}]/8BM
+Memory allocation (code space): 48
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\p{Nd}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[\p{Nd}+-]+/8BM
+Memory allocation (code space): 84
+------------------------------------------------------------------
+ 0 18 Bra
+ 2 [+\-\p{Nd}]++
+ 18 18 Ket
+ 20 End
+------------------------------------------------------------------
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM
+Memory allocation (code space): 60
+------------------------------------------------------------------
+ 0 12 Bra
+ 2 /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
+ 12 12 Ket
+ 14 End
+------------------------------------------------------------------
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM
+Memory allocation (code space): 60
+------------------------------------------------------------------
+ 0 12 Bra
+ 2 A\x{391}\x{10427}\x{ff3a}\x{1fb0}
+ 12 12 Ket
+ 14 End
+------------------------------------------------------------------
+
+/[\x{105}-\x{109}]/8iBM
+Memory allocation (code space): 48
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [\x{104}-\x{109}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/( ( (?(1)0|) )* )/xBM
+Memory allocation (code space): 104
+------------------------------------------------------------------
+ 0 23 Bra
+ 2 19 CBra 1
+ 5 Brazero
+ 6 13 SCBra 2
+ 9 6 Cond
+ 11 1 Cond ref
+ 13 0
+ 15 2 Alt
+ 17 8 Ket
+ 19 13 KetRmax
+ 21 19 Ket
+ 23 23 Ket
+ 25 End
+------------------------------------------------------------------
+
+/( (?(1)0|)* )/xBM
+Memory allocation (code space): 84
+------------------------------------------------------------------
+ 0 18 Bra
+ 2 14 CBra 1
+ 5 Brazero
+ 6 6 SCond
+ 8 1 Cond ref
+ 10 0
+ 12 2 Alt
+ 14 8 KetRmax
+ 16 14 Ket
+ 18 18 Ket
+ 20 End
+------------------------------------------------------------------
+
+/[a]/BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 a
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[a]/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 a
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[\xaa]/BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{aa}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[\xaa]/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 \x{aa}
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[^a]/BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 [^a]
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[^a]/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 [^a]
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[^\xaa]/BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 [^\x{aa}]
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[^\xaa]/8BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 4 Bra
+ 2 [^\x{aa}]
+ 4 4 Ket
+ 6 End
+------------------------------------------------------------------
+
+/[^\d]/8WB
+------------------------------------------------------------------
+ 0 9 Bra
+ 2 [^\p{Nd}]
+ 9 9 Ket
+ 11 End
+------------------------------------------------------------------
+
+/[[:^alpha:][:^cntrl:]]+/8WB
+------------------------------------------------------------------
+ 0 18 Bra
+ 2 [ -~\x80-\xff\P{L}]++
+ 18 18 Ket
+ 20 End
+------------------------------------------------------------------
+
+/[[:^cntrl:][:^alpha:]]+/8WB
+------------------------------------------------------------------
+ 0 18 Bra
+ 2 [ -~\x80-\xff\P{L}]++
+ 18 18 Ket
+ 20 End
+------------------------------------------------------------------
+
+/[[:alpha:]]+/8WB
+------------------------------------------------------------------
+ 0 10 Bra
+ 2 [\p{L}]++
+ 10 10 Ket
+ 12 End
+------------------------------------------------------------------
+
+/[[:^alpha:]\S]+/8WB
+------------------------------------------------------------------
+ 0 13 Bra
+ 2 [\P{L}\P{Xsp}]++
+ 13 13 Ket
+ 15 End
+------------------------------------------------------------------
+
+/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B
+------------------------------------------------------------------
+ 0 60 Bra
+ 2 abc
+ 8 5 CBra 1
+ 11 d
+ 13 4 Alt
+ 15 e
+ 17 9 Ket
+ 19 *THEN
+ 20 x
+ 22 12 CBra 2
+ 25 123
+ 31 *THEN
+ 32 4
+ 34 24 Alt
+ 36 567
+ 42 5 CBra 3
+ 45 b
+ 47 4 Alt
+ 49 q
+ 51 9 Ket
+ 53 *THEN
+ 54 xx
+ 58 36 Ket
+ 60 60 Ket
+ 62 End
+------------------------------------------------------------------
+
+/-- End of testinput11 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput11-8 b/ext/pcre/pcrelib/testdata/testoutput11-8
new file mode 100644
index 0000000000..d4a21334e3
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput11-8
@@ -0,0 +1,712 @@
+/-- These are a few representative patterns whose lengths and offsets are to be
+shown when the link size is 2. This is just a doublecheck test to ensure the
+sizes don't go horribly wrong when something is changed. The pattern contents
+are all themselves checked in other tests. Unicode, including property support,
+is required for these tests. --/
+
+/((?i)b)/BM
+Memory allocation (code space): 17
+------------------------------------------------------------------
+ 0 13 Bra
+ 3 7 CBra 1
+ 8 /i b
+ 10 7 Ket
+ 13 13 Ket
+ 16 End
+------------------------------------------------------------------
+
+/(?s)(.*X|^B)/BM
+Memory allocation (code space): 25
+------------------------------------------------------------------
+ 0 21 Bra
+ 3 9 CBra 1
+ 8 AllAny*
+ 10 X
+ 12 6 Alt
+ 15 ^
+ 16 B
+ 18 15 Ket
+ 21 21 Ket
+ 24 End
+------------------------------------------------------------------
+
+/(?s:.*X|^B)/BM
+Memory allocation (code space): 23
+------------------------------------------------------------------
+ 0 19 Bra
+ 3 7 Bra
+ 6 AllAny*
+ 8 X
+ 10 6 Alt
+ 13 ^
+ 14 B
+ 16 13 Ket
+ 19 19 Ket
+ 22 End
+------------------------------------------------------------------
+
+/^[[:alnum:]]/BM
+Memory allocation (code space): 41
+------------------------------------------------------------------
+ 0 37 Bra
+ 3 ^
+ 4 [0-9A-Za-z]
+ 37 37 Ket
+ 40 End
+------------------------------------------------------------------
+
+/#/IxMD
+Memory allocation (code space): 7
+------------------------------------------------------------------
+ 0 3 Bra
+ 3 3 Ket
+ 6 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+May match empty string
+Options: extended
+No first char
+No need char
+
+/a#/IxMD
+Memory allocation (code space): 9
+------------------------------------------------------------------
+ 0 5 Bra
+ 3 a
+ 5 5 Ket
+ 8 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: extended
+First char = 'a'
+No need char
+
+/x?+/BM
+Memory allocation (code space): 9
+------------------------------------------------------------------
+ 0 5 Bra
+ 3 x?+
+ 5 5 Ket
+ 8 End
+------------------------------------------------------------------
+
+/x++/BM
+Memory allocation (code space): 9
+------------------------------------------------------------------
+ 0 5 Bra
+ 3 x++
+ 5 5 Ket
+ 8 End
+------------------------------------------------------------------
+
+/x{1,3}+/BM
+Memory allocation (code space): 13
+------------------------------------------------------------------
+ 0 9 Bra
+ 3 x
+ 5 x{0,2}+
+ 9 9 Ket
+ 12 End
+------------------------------------------------------------------
+
+/(x)*+/BM
+Memory allocation (code space): 18
+------------------------------------------------------------------
+ 0 14 Bra
+ 3 Braposzero
+ 4 7 CBraPos 1
+ 9 x
+ 11 7 KetRpos
+ 14 14 Ket
+ 17 End
+------------------------------------------------------------------
+
+/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/BM
+Memory allocation (code space): 120
+------------------------------------------------------------------
+ 0 116 Bra
+ 3 ^
+ 4 109 CBra 1
+ 9 7 CBra 2
+ 14 a+
+ 16 7 Ket
+ 19 39 CBra 3
+ 24 [ab]+?
+ 58 39 Ket
+ 61 39 CBra 4
+ 66 [bc]+
+100 39 Ket
+103 7 CBra 5
+108 \w*+
+110 7 Ket
+113 109 Ket
+116 116 Ket
+119 End
+------------------------------------------------------------------
+
+|8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM
+Memory allocation (code space): 826
+------------------------------------------------------------------
+ 0 822 Bra
+ 3 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
+821 \b
+822 822 Ket
+825 End
+------------------------------------------------------------------
+
+|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|BM
+Memory allocation (code space): 816
+------------------------------------------------------------------
+ 0 812 Bra
+ 3 $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
+811 \b
+812 812 Ket
+815 End
+------------------------------------------------------------------
+
+/(a(?1)b)/BM
+Memory allocation (code space): 22
+------------------------------------------------------------------
+ 0 18 Bra
+ 3 12 CBra 1
+ 8 a
+ 10 3 Recurse
+ 13 b
+ 15 12 Ket
+ 18 18 Ket
+ 21 End
+------------------------------------------------------------------
+
+/(a(?1)+b)/BM
+Memory allocation (code space): 28
+------------------------------------------------------------------
+ 0 24 Bra
+ 3 18 CBra 1
+ 8 a
+ 10 6 Once
+ 13 3 Recurse
+ 16 6 KetRmax
+ 19 b
+ 21 18 Ket
+ 24 24 Ket
+ 27 End
+------------------------------------------------------------------
+
+/a(?P<name1>b|c)d(?P<longername2>e)/BM
+Memory allocation (code space): 36
+------------------------------------------------------------------
+ 0 32 Bra
+ 3 a
+ 5 7 CBra 1
+ 10 b
+ 12 5 Alt
+ 15 c
+ 17 12 Ket
+ 20 d
+ 22 7 CBra 2
+ 27 e
+ 29 7 Ket
+ 32 32 Ket
+ 35 End
+------------------------------------------------------------------
+
+/(?:a(?P<c>c(?P<d>d)))(?P<a>a)/BM
+Memory allocation (code space): 45
+------------------------------------------------------------------
+ 0 41 Bra
+ 3 25 Bra
+ 6 a
+ 8 17 CBra 1
+ 13 c
+ 15 7 CBra 2
+ 20 d
+ 22 7 Ket
+ 25 17 Ket
+ 28 25 Ket
+ 31 7 CBra 3
+ 36 a
+ 38 7 Ket
+ 41 41 Ket
+ 44 End
+------------------------------------------------------------------
+
+/(?P<a>a)...(?P=a)bbb(?P>a)d/BM
+Memory allocation (code space): 34
+------------------------------------------------------------------
+ 0 30 Bra
+ 3 7 CBra 1
+ 8 a
+ 10 7 Ket
+ 13 Any
+ 14 Any
+ 15 Any
+ 16 \1
+ 19 bbb
+ 25 3 Recurse
+ 28 d
+ 30 30 Ket
+ 33 End
+------------------------------------------------------------------
+
+/abc(?C255)de(?C)f/BM
+Memory allocation (code space): 31
+------------------------------------------------------------------
+ 0 27 Bra
+ 3 abc
+ 9 Callout 255 10 1
+ 15 de
+ 19 Callout 0 16 1
+ 25 f
+ 27 27 Ket
+ 30 End
+------------------------------------------------------------------
+
+/abcde/CBM
+Memory allocation (code space): 53
+------------------------------------------------------------------
+ 0 49 Bra
+ 3 Callout 255 0 1
+ 9 a
+ 11 Callout 255 1 1
+ 17 b
+ 19 Callout 255 2 1
+ 25 c
+ 27 Callout 255 3 1
+ 33 d
+ 35 Callout 255 4 1
+ 41 e
+ 43 Callout 255 5 0
+ 49 49 Ket
+ 52 End
+------------------------------------------------------------------
+
+/\x{100}/8BM
+Memory allocation (code space): 10
+------------------------------------------------------------------
+ 0 6 Bra
+ 3 \x{100}
+ 6 6 Ket
+ 9 End
+------------------------------------------------------------------
+
+/\x{1000}/8BM
+Memory allocation (code space): 11
+------------------------------------------------------------------
+ 0 7 Bra
+ 3 \x{1000}
+ 7 7 Ket
+ 10 End
+------------------------------------------------------------------
+
+/\x{10000}/8BM
+Memory allocation (code space): 12
+------------------------------------------------------------------
+ 0 8 Bra
+ 3 \x{10000}
+ 8 8 Ket
+ 11 End
+------------------------------------------------------------------
+
+/\x{100000}/8BM
+Memory allocation (code space): 12
+------------------------------------------------------------------
+ 0 8 Bra
+ 3 \x{100000}
+ 8 8 Ket
+ 11 End
+------------------------------------------------------------------
+
+/\x{10ffff}/8BM
+Memory allocation (code space): 12
+------------------------------------------------------------------
+ 0 8 Bra
+ 3 \x{10ffff}
+ 8 8 Ket
+ 11 End
+------------------------------------------------------------------
+
+/\x{110000}/8BM
+Failed: character value in \x{} or \o{} is too large at offset 9
+
+/[\x{ff}]/8BM
+Memory allocation (code space): 10
+------------------------------------------------------------------
+ 0 6 Bra
+ 3 \x{ff}
+ 6 6 Ket
+ 9 End
+------------------------------------------------------------------
+
+/[\x{100}]/8BM
+Memory allocation (code space): 10
+------------------------------------------------------------------
+ 0 6 Bra
+ 3 \x{100}
+ 6 6 Ket
+ 9 End
+------------------------------------------------------------------
+
+/\x80/8BM
+Memory allocation (code space): 10
+------------------------------------------------------------------
+ 0 6 Bra
+ 3 \x{80}
+ 6 6 Ket
+ 9 End
+------------------------------------------------------------------
+
+/\xff/8BM
+Memory allocation (code space): 10
+------------------------------------------------------------------
+ 0 6 Bra
+ 3 \x{ff}
+ 6 6 Ket
+ 9 End
+------------------------------------------------------------------
+
+/\x{0041}\x{2262}\x{0391}\x{002e}/D8M
+Memory allocation (code space): 18
+------------------------------------------------------------------
+ 0 14 Bra
+ 3 A\x{2262}\x{391}.
+ 14 14 Ket
+ 17 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'A'
+Need char = '.'
+
+/\x{D55c}\x{ad6d}\x{C5B4}/D8M
+Memory allocation (code space): 19
+------------------------------------------------------------------
+ 0 15 Bra
+ 3 \x{d55c}\x{ad6d}\x{c5b4}
+ 15 15 Ket
+ 18 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{ed}
+Need char = \x{b4}
+
+/\x{65e5}\x{672c}\x{8a9e}/D8M
+Memory allocation (code space): 19
+------------------------------------------------------------------
+ 0 15 Bra
+ 3 \x{65e5}\x{672c}\x{8a9e}
+ 15 15 Ket
+ 18 End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{e6}
+Need char = \x{9e}
+
+/[\x{100}]/8BM
+Memory allocation (code space): 10
+------------------------------------------------------------------
+ 0 6 Bra
+ 3 \x{100}
+ 6 6 Ket
+ 9 End
+------------------------------------------------------------------
+
+/[Z\x{100}]/8BM
+Memory allocation (code space): 47
+------------------------------------------------------------------
+ 0 43 Bra
+ 3 [Z\x{100}]
+ 43 43 Ket
+ 46 End
+------------------------------------------------------------------
+
+/^[\x{100}\E-\Q\E\x{150}]/B8M
+Memory allocation (code space): 18
+------------------------------------------------------------------
+ 0 14 Bra
+ 3 ^
+ 4 [\x{100}-\x{150}]
+ 14 14 Ket
+ 17 End
+------------------------------------------------------------------
+
+/^[\QĀ\E-\QŐ\E]/B8M
+Memory allocation (code space): 18
+------------------------------------------------------------------
+ 0 14 Bra
+ 3 ^
+ 4 [\x{100}-\x{150}]
+ 14 14 Ket
+ 17 End
+------------------------------------------------------------------
+
+/^[\QĀ\E-\QŐ\E/B8M
+Failed: missing terminating ] for character class at offset 15
+
+/[\p{L}]/BM
+Memory allocation (code space): 15
+------------------------------------------------------------------
+ 0 11 Bra
+ 3 [\p{L}]
+ 11 11 Ket
+ 14 End
+------------------------------------------------------------------
+
+/[\p{^L}]/BM
+Memory allocation (code space): 15
+------------------------------------------------------------------
+ 0 11 Bra
+ 3 [\P{L}]
+ 11 11 Ket
+ 14 End
+------------------------------------------------------------------
+
+/[\P{L}]/BM
+Memory allocation (code space): 15
+------------------------------------------------------------------
+ 0 11 Bra
+ 3 [\P{L}]
+ 11 11 Ket
+ 14 End
+------------------------------------------------------------------
+
+/[\P{^L}]/BM
+Memory allocation (code space): 15
+------------------------------------------------------------------
+ 0 11 Bra
+ 3 [\p{L}]
+ 11 11 Ket
+ 14 End
+------------------------------------------------------------------
+
+/[abc\p{L}\x{0660}]/8BM
+Memory allocation (code space): 50
+------------------------------------------------------------------
+ 0 46 Bra
+ 3 [a-c\p{L}\x{660}]
+ 46 46 Ket
+ 49 End
+------------------------------------------------------------------
+
+/[\p{Nd}]/8BM
+Memory allocation (code space): 15
+------------------------------------------------------------------
+ 0 11 Bra
+ 3 [\p{Nd}]
+ 11 11 Ket
+ 14 End
+------------------------------------------------------------------
+
+/[\p{Nd}+-]+/8BM
+Memory allocation (code space): 48
+------------------------------------------------------------------
+ 0 44 Bra
+ 3 [+\-\p{Nd}]++
+ 44 44 Ket
+ 47 End
+------------------------------------------------------------------
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iBM
+Memory allocation (code space): 25
+------------------------------------------------------------------
+ 0 21 Bra
+ 3 /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
+ 21 21 Ket
+ 24 End
+------------------------------------------------------------------
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8BM
+Memory allocation (code space): 25
+------------------------------------------------------------------
+ 0 21 Bra
+ 3 A\x{391}\x{10427}\x{ff3a}\x{1fb0}
+ 21 21 Ket
+ 24 End
+------------------------------------------------------------------
+
+/[\x{105}-\x{109}]/8iBM
+Memory allocation (code space): 17
+------------------------------------------------------------------
+ 0 13 Bra
+ 3 [\x{104}-\x{109}]
+ 13 13 Ket
+ 16 End
+------------------------------------------------------------------
+
+/( ( (?(1)0|) )* )/xBM
+Memory allocation (code space): 38
+------------------------------------------------------------------
+ 0 34 Bra
+ 3 28 CBra 1
+ 8 Brazero
+ 9 19 SCBra 2
+ 14 8 Cond
+ 17 1 Cond ref
+ 20 0
+ 22 3 Alt
+ 25 11 Ket
+ 28 19 KetRmax
+ 31 28 Ket
+ 34 34 Ket
+ 37 End
+------------------------------------------------------------------
+
+/( (?(1)0|)* )/xBM
+Memory allocation (code space): 30
+------------------------------------------------------------------
+ 0 26 Bra
+ 3 20 CBra 1
+ 8 Brazero
+ 9 8 SCond
+ 12 1 Cond ref
+ 15 0
+ 17 3 Alt
+ 20 11 KetRmax
+ 23 20 Ket
+ 26 26 Ket
+ 29 End
+------------------------------------------------------------------
+
+/[a]/BM
+Memory allocation (code space): 9
+------------------------------------------------------------------
+ 0 5 Bra
+ 3 a
+ 5 5 Ket
+ 8 End
+------------------------------------------------------------------
+
+/[a]/8BM
+Memory allocation (code space): 9
+------------------------------------------------------------------
+ 0 5 Bra
+ 3 a
+ 5 5 Ket
+ 8 End
+------------------------------------------------------------------
+
+/[\xaa]/BM
+Memory allocation (code space): 9
+------------------------------------------------------------------
+ 0 5 Bra
+ 3 \x{aa}
+ 5 5 Ket
+ 8 End
+------------------------------------------------------------------
+
+/[\xaa]/8BM
+Memory allocation (code space): 10
+------------------------------------------------------------------
+ 0 6 Bra
+ 3 \x{aa}
+ 6 6 Ket
+ 9 End
+------------------------------------------------------------------
+
+/[^a]/BM
+Memory allocation (code space): 9
+------------------------------------------------------------------
+ 0 5 Bra
+ 3 [^a]
+ 5 5 Ket
+ 8 End
+------------------------------------------------------------------
+
+/[^a]/8BM
+Memory allocation (code space): 9
+------------------------------------------------------------------
+ 0 5 Bra
+ 3 [^a]
+ 5 5 Ket
+ 8 End
+------------------------------------------------------------------
+
+/[^\xaa]/BM
+Memory allocation (code space): 9
+------------------------------------------------------------------
+ 0 5 Bra
+ 3 [^\x{aa}]
+ 5 5 Ket
+ 8 End
+------------------------------------------------------------------
+
+/[^\xaa]/8BM
+Memory allocation (code space): 10
+------------------------------------------------------------------
+ 0 6 Bra
+ 3 [^\x{aa}]
+ 6 6 Ket
+ 9 End
+------------------------------------------------------------------
+
+/[^\d]/8WB
+------------------------------------------------------------------
+ 0 11 Bra
+ 3 [^\p{Nd}]
+ 11 11 Ket
+ 14 End
+------------------------------------------------------------------
+
+/[[:^alpha:][:^cntrl:]]+/8WB
+------------------------------------------------------------------
+ 0 44 Bra
+ 3 [ -~\x80-\xff\P{L}]++
+ 44 44 Ket
+ 47 End
+------------------------------------------------------------------
+
+/[[:^cntrl:][:^alpha:]]+/8WB
+------------------------------------------------------------------
+ 0 44 Bra
+ 3 [ -~\x80-\xff\P{L}]++
+ 44 44 Ket
+ 47 End
+------------------------------------------------------------------
+
+/[[:alpha:]]+/8WB
+------------------------------------------------------------------
+ 0 12 Bra
+ 3 [\p{L}]++
+ 12 12 Ket
+ 15 End
+------------------------------------------------------------------
+
+/[[:^alpha:]\S]+/8WB
+------------------------------------------------------------------
+ 0 15 Bra
+ 3 [\P{L}\P{Xsp}]++
+ 15 15 Ket
+ 18 End
+------------------------------------------------------------------
+
+/abc(d|e)(*THEN)x(123(*THEN)4|567(b|q)(*THEN)xx)/B
+------------------------------------------------------------------
+ 0 73 Bra
+ 3 abc
+ 9 7 CBra 1
+ 14 d
+ 16 5 Alt
+ 19 e
+ 21 12 Ket
+ 24 *THEN
+ 25 x
+ 27 14 CBra 2
+ 32 123
+ 38 *THEN
+ 39 4
+ 41 29 Alt
+ 44 567
+ 50 7 CBra 3
+ 55 b
+ 57 5 Alt
+ 60 q
+ 62 12 Ket
+ 65 *THEN
+ 66 xx
+ 70 43 Ket
+ 73 73 Ket
+ 76 End
+------------------------------------------------------------------
+
+/-- End of testinput11 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput12 b/ext/pcre/pcrelib/testdata/testoutput12
new file mode 100644
index 0000000000..a76e2aef88
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput12
@@ -0,0 +1,179 @@
+/-- This test is run only when JIT support is available. It checks for a
+successful and an unsuccessful JIT compile and save and restore behaviour,
+and a couple of things that are different with JIT. --/
+
+/abc/S+I
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'c'
+Subject length lower bound = 3
+No set of starting bytes
+JIT study was successful
+
+/(?(?C1)(?=a)a)/S+I
+Capturing subpattern count = 0
+May match empty string
+No options
+No first char
+No need char
+Study returned NULL
+JIT study was not successful
+
+/(?(?C1)(?=a)a)/S!+I
+Capturing subpattern count = 0
+May match empty string
+No options
+No first char
+No need char
+Subject length lower bound = -1
+No set of starting bytes
+JIT study was not successful
+
+/abc/S+I>testsavedregex
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'c'
+Subject length lower bound = 3
+No set of starting bytes
+JIT study was successful
+Compiled pattern written to testsavedregex
+Study data written to testsavedregex
+
+<testsavedregex
+Compiled pattern loaded from testsavedregex
+Study data loaded from testsavedregex
+ abc
+ 0: abc
+
+/a*/SI
+Capturing subpattern count = 0
+May match empty string
+No options
+No first char
+No need char
+Study returned NULL
+
+/(?(R)a*(?1)|((?R))b)/S+
+ aaaabcde
+Error -27 (JIT stack limit reached)
+
+/-- Test various compile modes --/
+
+/abcd/S++
+ abcd
+ 0: abcd (JIT)
+ xyz
+No match (JIT)
+
+/abcd/S+
+ abcd
+ 0: abcd (JIT)
+ ab\P
+Partial match: ab (JIT)
+ ab\P\P
+Partial match: ab (JIT)
+ xyz
+No match (JIT)
+
+/abcd/S++
+ abcd
+ 0: abcd (JIT)
+ ab\P
+Partial match: ab (JIT)
+ ab\P\P
+Partial match: ab (JIT)
+ xyz
+No match (JIT)
+
+/abcd/S++1
+ abcd
+ 0: abcd (JIT)
+ ab\P
+Partial match: ab
+ ab\P\P
+Partial match: ab
+ xyz
+No match (JIT)
+ xyz\P
+No match
+
+/abcd/S++2
+ abcd
+ 0: abcd
+ ab\P
+Partial match: ab (JIT)
+ ab\P\P
+Partial match: ab
+ xyz
+No match
+
+/abcd/S++3
+ abcd
+ 0: abcd (JIT)
+ ab\P
+Partial match: ab (JIT)
+ ab\P\P
+Partial match: ab
+ xyz
+No match (JIT)
+
+/abcd/S++4
+ abcd
+ 0: abcd
+ ab\P
+Partial match: ab
+ ab\P\P
+Partial match: ab (JIT)
+ xyz
+No match
+
+/abcd/S++5
+ abcd
+ 0: abcd (JIT)
+ ab\P
+Partial match: ab
+ ab\P\P
+Partial match: ab (JIT)
+ xyz
+No match (JIT)
+
+/abcd/S++6
+ abcd
+ 0: abcd
+ ab\P
+Partial match: ab (JIT)
+ ab\P\P
+Partial match: ab (JIT)
+ xyz
+No match
+
+/abcd/S++7
+ abcd
+ 0: abcd (JIT)
+ ab\P
+Partial match: ab (JIT)
+ ab\P\P
+Partial match: ab (JIT)
+ xyz
+No match (JIT)
+
+/abcd/S++2I
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'd'
+Subject length lower bound = 4
+No set of starting bytes
+JIT study was successful
+
+/(*NO_START_OPT)a(*:m)b/KS++
+ a
+No match, mark = m (JIT)
+
+/^12345678abcd/mS++
+ 12345678abcd
+ 0: 12345678abcd (JIT)
+
+/-- End of testinput12 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput13 b/ext/pcre/pcrelib/testdata/testoutput13
new file mode 100644
index 0000000000..9f73c5000f
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput13
@@ -0,0 +1,22 @@
+/-- This test is run only when JIT support is not available. It checks that an
+attempt to use it has the expected behaviour. It also tests things that
+are different without JIT. --/
+
+/abc/S+I
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'c'
+Subject length lower bound = 3
+No set of starting bytes
+JIT support is not available in this version of PCRE
+
+/a*/SI
+Capturing subpattern count = 0
+May match empty string
+No options
+No first char
+No need char
+Study returned NULL
+
+/-- End of testinput13 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput14 b/ext/pcre/pcrelib/testdata/testoutput14
new file mode 100644
index 0000000000..52680a8f9c
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput14
@@ -0,0 +1,530 @@
+/-- This set of tests is run only with the 8-bit library. They do not require
+ UTF-8 or Unicode property support. The file starts with all the tests of
+ the POSIX interface, because that is supported only with the 8-bit library.
+ --/
+
+< forbid 8W
+
+/abc/P
+ abc
+ 0: abc
+ *** Failers
+No match: POSIX code 17: match failed
+
+/^abc|def/P
+ abcdef
+ 0: abc
+ abcdef\B
+ 0: def
+
+/.*((abc)$|(def))/P
+ defabc
+ 0: defabc
+ 1: abc
+ 2: abc
+ \Zdefabc
+ 0: def
+ 1: def
+ 3: def
+
+/the quick brown fox/P
+ the quick brown fox
+ 0: the quick brown fox
+ *** Failers
+No match: POSIX code 17: match failed
+ The Quick Brown Fox
+No match: POSIX code 17: match failed
+
+/the quick brown fox/Pi
+ the quick brown fox
+ 0: the quick brown fox
+ The Quick Brown Fox
+ 0: The Quick Brown Fox
+
+/abc.def/P
+ *** Failers
+No match: POSIX code 17: match failed
+ abc\ndef
+No match: POSIX code 17: match failed
+
+/abc$/P
+ abc
+ 0: abc
+ abc\n
+ 0: abc
+
+/(abc)\2/P
+Failed: POSIX code 15: bad back reference at offset 7
+
+/(abc\1)/P
+ abc
+No match: POSIX code 17: match failed
+
+/a*(b+)(z)(z)/P
+ aaaabbbbzzzz
+ 0: aaaabbbbzz
+ 1: bbbb
+ 2: z
+ 3: z
+ aaaabbbbzzzz\O0
+ aaaabbbbzzzz\O1
+ 0: aaaabbbbzz
+ aaaabbbbzzzz\O2
+ 0: aaaabbbbzz
+ 1: bbbb
+ aaaabbbbzzzz\O3
+ 0: aaaabbbbzz
+ 1: bbbb
+ 2: z
+ aaaabbbbzzzz\O4
+ 0: aaaabbbbzz
+ 1: bbbb
+ 2: z
+ 3: z
+ aaaabbbbzzzz\O5
+ 0: aaaabbbbzz
+ 1: bbbb
+ 2: z
+ 3: z
+
+/ab.cd/P
+ ab-cd
+ 0: ab-cd
+ ab=cd
+ 0: ab=cd
+ ** Failers
+No match: POSIX code 17: match failed
+ ab\ncd
+No match: POSIX code 17: match failed
+
+/ab.cd/Ps
+ ab-cd
+ 0: ab-cd
+ ab=cd
+ 0: ab=cd
+ ab\ncd
+ 0: ab\x0acd
+
+/a(b)c/PN
+ abc
+Matched with REG_NOSUB
+
+/a(?P<name>b)c/PN
+ abc
+Matched with REG_NOSUB
+
+/a?|b?/P
+ abc
+ 0: a
+ ** Failers
+ 0:
+ ddd\N
+No match: POSIX code 17: match failed
+
+/\w+A/P
+ CDAAAAB
+ 0: CDAAAA
+
+/\w+A/PU
+ CDAAAAB
+ 0: CDA
+
+/\Biss\B/I+P
+ Mississippi
+ 0: iss
+ 0+ issippi
+
+/abc/\P
+Failed: POSIX code 9: bad escape sequence at offset 4
+
+/-- End of POSIX tests --/
+
+/a\Cb/
+ aXb
+ 0: aXb
+ a\nb
+ 0: a\x0ab
+ ** Failers (too big char)
+No match
+ A\x{123}B
+** Character \x{123} is greater than 255 and UTF-8 mode is not enabled.
+** Truncation will probably give the wrong result.
+No match
+ A\o{443}B
+** Character \x{123} is greater than 255 and UTF-8 mode is not enabled.
+** Truncation will probably give the wrong result.
+No match
+
+/\x{100}/I
+Failed: character value in \x{} or \o{} is too large at offset 6
+
+/\o{400}/I
+Failed: character value in \x{} or \o{} is too large at offset 6
+
+/ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional leading comment
+(?: (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address
+| # or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # one word, optionally followed by....
+(?:
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or...
+\(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) | # comments, or...
+
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+# quoted strings
+)*
+< (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # leading <
+(?: @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* , (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+)* # further okay, if led by comma
+: # closing colon
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* )? # optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address spec
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* > # trailing >
+# name and address
+) (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional trailing comment
+/xSI
+Capturing subpattern count = 0
+Contains explicit CR or LF match
+Options: extended
+No first char
+No need char
+Subject length lower bound = 3
+Starting byte set: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8
+ 9 = ? A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ^ _ ` a b c d e
+ f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f
+
+/-- Although this saved pattern was compiled with link-size=2, it does no harm
+to run this test with other link sizes because it is going to generated a
+"compiled in wrong mode" error as soon as it is loaded, so the link size does
+not matter. --/
+
+<!testsaved16
+Compiled pattern loaded from testsaved16
+No study data
+Error -28 from pcre_fullinfo(0)
+Running in 8-bit mode but pattern was compiled in 16-bit mode
+
+<!testsaved32
+Compiled pattern loaded from testsaved32
+No study data
+Error -28 from pcre_fullinfo(0)
+Running in 8-bit mode but pattern was compiled in 32-bit mode
+
+/\h/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x09 \x20 \xa0
+
+/\H/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/\v/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \x85
+
+/\V/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/\R/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \x85
+
+/[\h]/BZ
+------------------------------------------------------------------
+ Bra
+ [\x09 \xa0]
+ Ket
+ End
+------------------------------------------------------------------
+ >\x09<
+ 0: \x09
+
+/[\h]+/BZ
+------------------------------------------------------------------
+ Bra
+ [\x09 \xa0]++
+ Ket
+ End
+------------------------------------------------------------------
+ >\x09\x20\xa0<
+ 0: \x09 \xa0
+
+/[\v]/BZ
+------------------------------------------------------------------
+ Bra
+ [\x0a-\x0d\x85]
+ Ket
+ End
+------------------------------------------------------------------
+
+/[\H]/BZ
+------------------------------------------------------------------
+ Bra
+ [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff]
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^\h]/BZ
+------------------------------------------------------------------
+ Bra
+ [\x00-\x08\x0a-\x1f!-\x9f\xa1-\xff] (neg)
+ Ket
+ End
+------------------------------------------------------------------
+
+/[\V]/BZ
+------------------------------------------------------------------
+ Bra
+ [\x00-\x09\x0e-\x84\x86-\xff]
+ Ket
+ End
+------------------------------------------------------------------
+
+/[\x0a\V]/BZ
+------------------------------------------------------------------
+ Bra
+ [\x00-\x0a\x0e-\x84\x86-\xff]
+ Ket
+ End
+------------------------------------------------------------------
+
+/\777/I
+Failed: octal value is greater than \377 in 8-bit non-UTF-8 mode at offset 3
+
+/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K
+Failed: name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN) at offset 259
+
+/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K
+ XX
+ 0: XX
+MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+
+/\u0100/<JS>
+Failed: character value in \u.... sequence is too large at offset 5
+
+/[\u0100-\u0200]/<JS>
+Failed: character value in \u.... sequence is too large at offset 6
+
+/[^\x00-a]{12,}[^b-\xff]*/BZ
+------------------------------------------------------------------
+ Bra
+ [b-\xff] (neg){12,}+
+ [\x00-a] (neg)*+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^\s]*\s* [^\W]+\W+ [^\d]*?\d0 [^\d\w]{4,6}?\w*A/BZ
+------------------------------------------------------------------
+ Bra
+ [\x00-\x08\x0e-\x1f!-\xff] (neg)*+
+ \s*
+
+ [0-9A-Z_a-z]++
+ \W+
+
+ [\x00-/:-\xff] (neg)*+
+ \d
+ 0
+ [\x00-/:-@[-^`{-\xff] (neg){4,6}+
+ \w*
+ A
+ Ket
+ End
+------------------------------------------------------------------
+
+/-- End of testinput14 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput15 b/ext/pcre/pcrelib/testdata/testoutput15
new file mode 100644
index 0000000000..5792be72df
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput15
@@ -0,0 +1,1139 @@
+/-- This set of tests is for UTF-8 support but not Unicode property support,
+ and is relevant only to the 8-bit library. --/
+
+< forbid W
+
+/X(\C{3})/8
+ X\x{1234}
+ 0: X\x{1234}
+ 1: \x{1234}
+
+/X(\C{4})/8
+ X\x{1234}YZ
+ 0: X\x{1234}Y
+ 1: \x{1234}Y
+
+/X\C*/8
+ XYZabcdce
+ 0: XYZabcdce
+
+/X\C*?/8
+ XYZabcde
+ 0: X
+
+/X\C{3,5}/8
+ Xabcdefg
+ 0: Xabcde
+ X\x{1234}
+ 0: X\x{1234}
+ X\x{1234}YZ
+ 0: X\x{1234}YZ
+ X\x{1234}\x{512}
+ 0: X\x{1234}\x{512}
+ X\x{1234}\x{512}YZ
+ 0: X\x{1234}\x{512}
+
+/X\C{3,5}?/8
+ Xabcdefg
+ 0: Xabc
+ X\x{1234}
+ 0: X\x{1234}
+ X\x{1234}YZ
+ 0: X\x{1234}
+ X\x{1234}\x{512}
+ 0: X\x{1234}
+
+/a\Cb/8
+ aXb
+ 0: aXb
+ a\nb
+ 0: a\x{0a}b
+
+/a\C\Cb/8
+ a\x{100}b
+ 0: a\x{100}b
+
+/ab\Cde/8
+ abXde
+ 0: abXde
+
+/a\C\Cb/8
+ a\x{100}b
+ 0: a\x{100}b
+ ** Failers
+No match
+ a\x{12257}b
+No match
+
+/[]/8
+Failed: invalid UTF-8 string at offset 1
+
+//8
+Failed: invalid UTF-8 string at offset 0
+
+/xxx/8
+Failed: invalid UTF-8 string at offset 0
+
+/xxx/8?DZSSO
+------------------------------------------------------------------
+ Bra
+ \X{c0}\X{c0}\X{c0}xxx
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: no_auto_possessify utf no_utf_check
+First char = \x{c3}
+Need char = 'x'
+
+/badutf/8
+ \xdf
+Error -10 (bad UTF-8 string) offset=0 reason=1
+ \xef
+Error -10 (bad UTF-8 string) offset=0 reason=2
+ \xef\x80
+Error -10 (bad UTF-8 string) offset=0 reason=1
+ \xf7
+Error -10 (bad UTF-8 string) offset=0 reason=3
+ \xf7\x80
+Error -10 (bad UTF-8 string) offset=0 reason=2
+ \xf7\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=1
+ \xfb
+Error -10 (bad UTF-8 string) offset=0 reason=4
+ \xfb\x80
+Error -10 (bad UTF-8 string) offset=0 reason=3
+ \xfb\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=2
+ \xfb\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=1
+ \xfd
+Error -10 (bad UTF-8 string) offset=0 reason=5
+ \xfd\x80
+Error -10 (bad UTF-8 string) offset=0 reason=4
+ \xfd\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=3
+ \xfd\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=2
+ \xfd\x80\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=1
+ \xdf\x7f
+Error -10 (bad UTF-8 string) offset=0 reason=6
+ \xef\x7f\x80
+Error -10 (bad UTF-8 string) offset=0 reason=6
+ \xef\x80\x7f
+Error -10 (bad UTF-8 string) offset=0 reason=7
+ \xf7\x7f\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=6
+ \xf7\x80\x7f\x80
+Error -10 (bad UTF-8 string) offset=0 reason=7
+ \xf7\x80\x80\x7f
+Error -10 (bad UTF-8 string) offset=0 reason=8
+ \xfb\x7f\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=6
+ \xfb\x80\x7f\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=7
+ \xfb\x80\x80\x7f\x80
+Error -10 (bad UTF-8 string) offset=0 reason=8
+ \xfb\x80\x80\x80\x7f
+Error -10 (bad UTF-8 string) offset=0 reason=9
+ \xfd\x7f\x80\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=6
+ \xfd\x80\x7f\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=7
+ \xfd\x80\x80\x7f\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=8
+ \xfd\x80\x80\x80\x7f\x80
+Error -10 (bad UTF-8 string) offset=0 reason=9
+ \xfd\x80\x80\x80\x80\x7f
+Error -10 (bad UTF-8 string) offset=0 reason=10
+ \xed\xa0\x80
+Error -10 (bad UTF-8 string) offset=0 reason=14
+ \xc0\x8f
+Error -10 (bad UTF-8 string) offset=0 reason=15
+ \xe0\x80\x8f
+Error -10 (bad UTF-8 string) offset=0 reason=16
+ \xf0\x80\x80\x8f
+Error -10 (bad UTF-8 string) offset=0 reason=17
+ \xf8\x80\x80\x80\x8f
+Error -10 (bad UTF-8 string) offset=0 reason=18
+ \xfc\x80\x80\x80\x80\x8f
+Error -10 (bad UTF-8 string) offset=0 reason=19
+ \x80
+Error -10 (bad UTF-8 string) offset=0 reason=20
+ \xfe
+Error -10 (bad UTF-8 string) offset=0 reason=21
+ \xff
+Error -10 (bad UTF-8 string) offset=0 reason=21
+
+/badutf/8
+ \xfb\x80\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=11
+ \xfd\x80\x80\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=12
+ \xf7\xbf\xbf\xbf
+Error -10 (bad UTF-8 string) offset=0 reason=13
+
+/shortutf/8
+ \P\P\xdf
+Error -25 (short UTF-8 string) offset=0 reason=1
+ \P\P\xef
+Error -25 (short UTF-8 string) offset=0 reason=2
+ \P\P\xef\x80
+Error -25 (short UTF-8 string) offset=0 reason=1
+ \P\P\xf7
+Error -25 (short UTF-8 string) offset=0 reason=3
+ \P\P\xf7\x80
+Error -25 (short UTF-8 string) offset=0 reason=2
+ \P\P\xf7\x80\x80
+Error -25 (short UTF-8 string) offset=0 reason=1
+ \P\P\xfb
+Error -25 (short UTF-8 string) offset=0 reason=4
+ \P\P\xfb\x80
+Error -25 (short UTF-8 string) offset=0 reason=3
+ \P\P\xfb\x80\x80
+Error -25 (short UTF-8 string) offset=0 reason=2
+ \P\P\xfb\x80\x80\x80
+Error -25 (short UTF-8 string) offset=0 reason=1
+ \P\P\xfd
+Error -25 (short UTF-8 string) offset=0 reason=5
+ \P\P\xfd\x80
+Error -25 (short UTF-8 string) offset=0 reason=4
+ \P\P\xfd\x80\x80
+Error -25 (short UTF-8 string) offset=0 reason=3
+ \P\P\xfd\x80\x80\x80
+Error -25 (short UTF-8 string) offset=0 reason=2
+ \P\P\xfd\x80\x80\x80\x80
+Error -25 (short UTF-8 string) offset=0 reason=1
+
+/anything/8
+ \xc0\x80
+Error -10 (bad UTF-8 string) offset=0 reason=15
+ \xc1\x8f
+Error -10 (bad UTF-8 string) offset=0 reason=15
+ \xe0\x9f\x80
+Error -10 (bad UTF-8 string) offset=0 reason=16
+ \xf0\x8f\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=17
+ \xf8\x87\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=18
+ \xfc\x83\x80\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=19
+ \xfe\x80\x80\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=21
+ \xff\x80\x80\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=21
+ \xc3\x8f
+No match
+ \xe0\xaf\x80
+No match
+ \xe1\x80\x80
+No match
+ \xf0\x9f\x80\x80
+No match
+ \xf1\x8f\x80\x80
+No match
+ \xf8\x88\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=11
+ \xf9\x87\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=11
+ \xfc\x84\x80\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=12
+ \xfd\x83\x80\x80\x80\x80
+Error -10 (bad UTF-8 string) offset=0 reason=12
+ \?\xf8\x88\x80\x80\x80
+No match
+ \?\xf9\x87\x80\x80\x80
+No match
+ \?\xfc\x84\x80\x80\x80\x80
+No match
+ \?\xfd\x83\x80\x80\x80\x80
+No match
+
+/\x{100}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c4}
+Need char = \x{80}
+
+/\x{1000}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{1000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{e1}
+Need char = \x{80}
+
+/\x{10000}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{10000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{f0}
+Need char = \x{80}
+
+/\x{100000}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{f4}
+Need char = \x{80}
+
+/\x{10ffff}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{10ffff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{f4}
+Need char = \x{bf}
+
+/[\x{ff}]/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{ff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c3}
+Need char = \x{bf}
+
+/[\x{100}]/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c4}
+Need char = \x{80}
+
+/\x80/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{80}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c2}
+Need char = \x{80}
+
+/\xff/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{ff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c3}
+Need char = \x{bf}
+
+/\x{D55c}\x{ad6d}\x{C5B4}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{d55c}\x{ad6d}\x{c5b4}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{ed}
+Need char = \x{b4}
+ \x{D55c}\x{ad6d}\x{C5B4}
+ 0: \x{d55c}\x{ad6d}\x{c5b4}
+
+/\x{65e5}\x{672c}\x{8a9e}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{65e5}\x{672c}\x{8a9e}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{e6}
+Need char = \x{9e}
+ \x{65e5}\x{672c}\x{8a9e}
+ 0: \x{65e5}\x{672c}\x{8a9e}
+
+/\x{80}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{80}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c2}
+Need char = \x{80}
+
+/\x{084}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{84}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c2}
+Need char = \x{84}
+
+/\x{104}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{104}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c4}
+Need char = \x{84}
+
+/\x{861}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{861}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{e0}
+Need char = \x{a1}
+
+/\x{212ab}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{212ab}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{f0}
+Need char = \x{ab}
+
+/-- This one is here not because it's different to Perl, but because the way
+the captured single-byte is displayed. (In Perl it becomes a character, and you
+can't tell the difference.) --/
+
+/X(\C)(.*)/8
+ X\x{1234}
+ 0: X\x{1234}
+ 1: \x{e1}
+ 2: \x{88}\x{b4}
+ X\nabc
+ 0: X\x{0a}abc
+ 1: \x{0a}
+ 2: abc
+
+/-- This one is here because Perl gives out a grumbly error message (quite
+correctly, but that messes up comparisons). --/
+
+/a\Cb/8
+ *** Failers
+No match
+ a\x{100}b
+No match
+
+/[^ab\xC0-\xF0]/8SDZ
+------------------------------------------------------------------
+ Bra
+ [\x00-`c-\xbf\xf1-\xff] (neg)
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
+ \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19
+ \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4
+ 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y
+ Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f
+ \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0
+ \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf
+ \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee
+ \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd
+ \xfe \xff
+ \x{f1}
+ 0: \x{f1}
+ \x{bf}
+ 0: \x{bf}
+ \x{100}
+ 0: \x{100}
+ \x{1000}
+ 0: \x{1000}
+ *** Failers
+ 0: *
+ \x{c0}
+No match
+ \x{f0}
+No match
+
+/Ā{3,4}/8SDZ
+------------------------------------------------------------------
+ Bra
+ \x{100}{3}
+ \x{100}?+
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c4}
+Need char = \x{80}
+Subject length lower bound = 3
+No set of starting bytes
+ \x{100}\x{100}\x{100}\x{100\x{100}
+ 0: \x{100}\x{100}\x{100}
+
+/(\x{100}+|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}++
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: x \xc4
+
+/(\x{100}*a|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}*+
+ a
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: a x \xc4
+
+/(\x{100}{0,2}a|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}{0,2}+
+ a
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: a x \xc4
+
+/(\x{100}{1,2}a|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}
+ \x{100}{0,1}+
+ a
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: x \xc4
+
+/\x{100}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c4}
+Need char = \x{80}
+
+/a\x{100}\x{101}*/8DZ
+------------------------------------------------------------------
+ Bra
+ a\x{100}
+ \x{101}*+
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'a'
+Need char = \x{80}
+
+/a\x{100}\x{101}+/8DZ
+------------------------------------------------------------------
+ Bra
+ a\x{100}
+ \x{101}++
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'a'
+Need char = \x{81}
+
+/[^\x{c4}]/DZ
+------------------------------------------------------------------
+ Bra
+ [^\x{c4}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/[\x{100}]/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c4}
+Need char = \x{80}
+ \x{100}
+ 0: \x{100}
+ Z\x{100}
+ 0: \x{100}
+ \x{100}Z
+ 0: \x{100}
+ *** Failers
+No match
+
+/[\xff]/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{ff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c3}
+Need char = \x{bf}
+ >\x{ff}<
+ 0: \x{ff}
+
+/[^\xff]/8DZ
+------------------------------------------------------------------
+ Bra
+ [^\x{ff}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+
+/\x{100}abc(xyz(?1))/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}abc
+ CBra 1
+ xyz
+ Recurse
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+First char = \x{c4}
+Need char = 'z'
+
+/a\x{1234}b/P8
+ a\x{1234}b
+ 0: a\x{1234}b
+
+/\777/8I
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c7}
+Need char = \x{bf}
+ \x{1ff}
+ 0: \x{1ff}
+ \777
+ 0: \x{1ff}
+
+/\x{100}+\x{200}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}++
+ \x{200}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c4}
+Need char = \x{80}
+
+/\x{100}+X/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}++
+ X
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c4}
+Need char = 'X'
+
+/^[\QĀ\E-\QŐ\E/BZ8
+Failed: missing terminating ] for character class at offset 15
+
+/-- This tests the stricter UTF-8 check according to RFC 3629. --/
+
+/X/8
+ \x{d800}
+Error -10 (bad UTF-8 string) offset=0 reason=14
+ \x{d800}\?
+No match
+ \x{da00}
+Error -10 (bad UTF-8 string) offset=0 reason=14
+ \x{da00}\?
+No match
+ \x{dfff}
+Error -10 (bad UTF-8 string) offset=0 reason=14
+ \x{dfff}\?
+No match
+ \x{110000}
+Error -10 (bad UTF-8 string) offset=0 reason=13
+ \x{110000}\?
+No match
+ \x{2000000}
+Error -10 (bad UTF-8 string) offset=0 reason=11
+ \x{2000000}\?
+No match
+ \x{7fffffff}
+Error -10 (bad UTF-8 string) offset=0 reason=12
+ \x{7fffffff}\?
+No match
+
+/(*UTF8)\x{1234}/
+ abcd\x{1234}pqr
+ 0: \x{1234}
+
+/(*CRLF)(*UTF)(*BSR_UNICODE)a\Rb/I
+Capturing subpattern count = 0
+Options: bsr_unicode utf
+Forced newline sequence: CRLF
+First char = 'a'
+Need char = 'b'
+
+/\h/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x09 \x20 \xc2 \xe1 \xe2 \xe3
+ ABC\x{09}
+ 0: \x{09}
+ ABC\x{20}
+ 0:
+ ABC\x{a0}
+ 0: \x{a0}
+ ABC\x{1680}
+ 0: \x{1680}
+ ABC\x{180e}
+ 0: \x{180e}
+ ABC\x{2000}
+ 0: \x{2000}
+ ABC\x{202f}
+ 0: \x{202f}
+ ABC\x{205f}
+ 0: \x{205f}
+ ABC\x{3000}
+ 0: \x{3000}
+
+/\v/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2
+ ABC\x{0a}
+ 0: \x{0a}
+ ABC\x{0b}
+ 0: \x{0b}
+ ABC\x{0c}
+ 0: \x{0c}
+ ABC\x{0d}
+ 0: \x{0d}
+ ABC\x{85}
+ 0: \x{85}
+ ABC\x{2028}
+ 0: \x{2028}
+
+/\h*A/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'A'
+Subject length lower bound = 1
+Starting byte set: \x09 \x20 A \xc2 \xe1 \xe2 \xe3
+ CDBABC
+ 0: A
+
+/\v+A/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'A'
+Subject length lower bound = 2
+Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2
+
+/\s?xxx\s/8SI
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'x'
+Subject length lower bound = 4
+Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 x
+
+/\sxxx\s/I8ST1
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'x'
+Subject length lower bound = 5
+Starting byte set: \x09 \x0a \x0c \x0d \x20 \xc2
+ AB\x{85}xxx\x{a0}XYZ
+ 0: \x{85}xxx\x{a0}
+ AB\x{a0}xxx\x{85}XYZ
+ 0: \x{a0}xxx\x{85}
+
+/\S \S/I8ST1
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = ' '
+Subject length lower bound = 3
+Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e
+ \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d
+ \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @
+ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e
+ f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xc0 \xc1 \xc2 \xc3
+ \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2
+ \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1
+ \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0
+ \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff
+ \x{a2} \x{84}
+ 0: \x{a2} \x{84}
+ A Z
+ 0: A Z
+
+/a+/8
+ a\x{123}aa\>1
+ 0: aa
+ a\x{123}aa\>2
+Error -11 (bad UTF-8 offset)
+ a\x{123}aa\>3
+ 0: aa
+ a\x{123}aa\>4
+ 0: a
+ a\x{123}aa\>5
+No match
+ a\x{123}aa\>6
+Error -24 (bad offset value)
+
+/\x{1234}+/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \xe1
+
+/\x{1234}+?/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \xe1
+
+/\x{1234}++/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \xe1
+
+/\x{1234}{2}/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+No first char
+No need char
+Subject length lower bound = 2
+Starting byte set: \xe1
+
+/[^\x{c4}]/8DZ
+------------------------------------------------------------------
+ Bra
+ [^\x{c4}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+
+/X+\x{200}/8DZ
+------------------------------------------------------------------
+ Bra
+ X++
+ \x{200}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'X'
+Need char = \x{80}
+
+/\R/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \xc2 \xe2
+
+/\777/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{1ff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{c7}
+Need char = \x{bf}
+
+/\w+\x{C4}/8BZ
+------------------------------------------------------------------
+ Bra
+ \w++
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ a\x{C4}\x{C4}
+ 0: a\x{c4}
+
+/\w+\x{C4}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \w+
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ a\x{C4}\x{C4}
+ 0: a\x{c4}\x{c4}
+
+/\W+\x{C4}/8BZ
+------------------------------------------------------------------
+ Bra
+ \W+
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{C4}
+ 0: !\x{c4}
+
+/\W+\x{C4}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \W++
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{C4}
+ 0: !\x{c4}
+
+/\W+\x{A1}/8BZ
+------------------------------------------------------------------
+ Bra
+ \W+
+ \x{a1}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{A1}
+ 0: !\x{a1}
+
+/\W+\x{A1}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \W+
+ \x{a1}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{A1}
+ 0: !\x{a1}
+
+/X\s+\x{A0}/8BZ
+------------------------------------------------------------------
+ Bra
+ X
+ \s++
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x20\x{A0}\x{A0}
+ 0: X \x{a0}
+
+/X\s+\x{A0}/8BZT1
+------------------------------------------------------------------
+ Bra
+ X
+ \s+
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x20\x{A0}\x{A0}
+ 0: X \x{a0}\x{a0}
+
+/\S+\x{A0}/8BZ
+------------------------------------------------------------------
+ Bra
+ \S+
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x{A0}\x{A0}
+ 0: X\x{a0}\x{a0}
+
+/\S+\x{A0}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \S++
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x{A0}\x{A0}
+ 0: X\x{a0}
+
+/\x{a0}+\s!/8BZ
+------------------------------------------------------------------
+ Bra
+ \x{a0}++
+ \s
+ !
+ Ket
+ End
+------------------------------------------------------------------
+ \x{a0}\x20!
+ 0: \x{a0} !
+
+/\x{a0}+\s!/8BZT1
+------------------------------------------------------------------
+ Bra
+ \x{a0}+
+ \s
+ !
+ Ket
+ End
+------------------------------------------------------------------
+ \x{a0}\x20!
+ 0: \x{a0} !
+
+/A/8
+ \x{ff000041}
+** Character \x{ff000041} is greater than 0x7fffffff and so cannot be converted to UTF-8
+ \x{7f000041}
+Error -10 (bad UTF-8 string) offset=0 reason=12
+
+/(*UTF8)abc/9
+Failed: setting UTF is disabled by the application at offset 0
+
+/abc/89
+Failed: setting UTF is disabled by the application at offset 0
+
+/-- End of testinput15 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput16 b/ext/pcre/pcrelib/testdata/testoutput16
new file mode 100644
index 0000000000..1d5f31d929
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput16
@@ -0,0 +1,121 @@
+/-- This set of tests is run only with the 8-bit library when Unicode property
+ support is available. It starts with tests of the POSIX interface, because
+ that is supported only with the 8-bit library. --/
+
+/\w/P
+ +++\x{c2}
+No match: POSIX code 17: match failed
+
+/\w/WP
+ +++\x{c2}
+ 0: \xc2
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ
+------------------------------------------------------------------
+ Bra
+ /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: caseless utf
+First char = 'A' (caseless)
+No need char
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ
+------------------------------------------------------------------
+ Bra
+ A\x{391}\x{10427}\x{ff3a}\x{1fb0}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'A'
+Need char = \x{b0}
+
+/AB\x{1fb0}/8DZ
+------------------------------------------------------------------
+ Bra
+ AB\x{1fb0}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'A'
+Need char = \x{b0}
+
+/AB\x{1fb0}/8DZi
+------------------------------------------------------------------
+ Bra
+ /i AB\x{1fb0}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: caseless utf
+First char = 'A' (caseless)
+Need char = 'B' (caseless)
+
+/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI
+Capturing subpattern count = 0
+Options: caseless utf
+No first char
+No need char
+Subject length lower bound = 17
+Starting byte set: \xd0 \xd1
+ \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}
+ 0: \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}
+ \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f}
+ 0: \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f}
+
+/[ⱥ]/8iBZ
+------------------------------------------------------------------
+ Bra
+ /i \x{2c65}
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^ⱥ]/8iBZ
+------------------------------------------------------------------
+ Bra
+ /i [^\x{2c65}]
+ Ket
+ End
+------------------------------------------------------------------
+
+/\h/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x09 \x20 \xa0
+
+/\v/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \x85
+
+/\R/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \x85
+
+/[[:blank:]]/WBZ
+------------------------------------------------------------------
+ Bra
+ [\x09 \xa0]
+ Ket
+ End
+------------------------------------------------------------------
+
+/-- End of testinput16 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput17 b/ext/pcre/pcrelib/testdata/testoutput17
new file mode 100644
index 0000000000..9a469c51ae
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput17
@@ -0,0 +1,558 @@
+/-- This set of tests is for the 16- and 32-bit library's basic (non-UTF-16
+ or -32) features that are not compatible with the 8-bit library, or which
+ give different output in 16- or 32-bit mode. --/
+
+< forbid 8W
+
+/a\Cb/
+ aXb
+ 0: aXb
+ a\nb
+ 0: a\x0ab
+
+/[^\x{c4}]/DZ
+------------------------------------------------------------------
+ Bra
+ [^\x{c4}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/\x{100}/I
+Capturing subpattern count = 0
+No options
+First char = \x{100}
+No need char
+
+/ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional leading comment
+(?: (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address
+| # or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # one word, optionally followed by....
+(?:
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or...
+\(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) | # comments, or...
+
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+# quoted strings
+)*
+< (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # leading <
+(?: @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* , (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+)* # further okay, if led by comma
+: # closing colon
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* )? # optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) # initial word
+(?: (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?: # opening quote...
+[^\\\x80-\xff\n\015"] # Anything except backslash and quote
+| # or
+\\ [^\x80-\xff] # Escaped something (something != CR)
+)* " # closing quote
+) )* # further okay, if led by a period
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* @ (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # initial subdomain
+(?: #
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* \. # if led by a period...
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+| \[ # [
+(?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff
+\] # ]
+) # ...further okay
+)*
+# address spec
+(?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* > # trailing >
+# name and address
+) (?: [\040\t] | \(
+(?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )*
+\) )* # optional trailing comment
+/xSI
+Capturing subpattern count = 0
+Contains explicit CR or LF match
+Options: extended
+No first char
+No need char
+Subject length lower bound = 3
+Starting byte set: \x09 \x20 ! " # $ % & ' ( * + - / 0 1 2 3 4 5 6 7 8
+ 9 = ? A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ^ _ ` a b c d e
+ f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xff
+
+/[\h]/BZ
+------------------------------------------------------------------
+ Bra
+ [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]
+ Ket
+ End
+------------------------------------------------------------------
+ >\x09<
+ 0: \x09
+
+/[\h]+/BZ
+------------------------------------------------------------------
+ Bra
+ [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]++
+ Ket
+ End
+------------------------------------------------------------------
+ >\x09\x20\xa0<
+ 0: \x09 \xa0
+
+/[\v]/BZ
+------------------------------------------------------------------
+ Bra
+ [\x0a-\x0d\x85\x{2028}-\x{2029}]
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^\h]/BZ
+------------------------------------------------------------------
+ Bra
+ [^\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]
+ Ket
+ End
+------------------------------------------------------------------
+
+/\h+/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x09 \x20 \xa0 \xff
+ \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000}
+ 0: \x{1680}\x{2000}\x{202f}\x{3000}
+ \x{3001}\x{2fff}\x{200a}\xa0\x{2000}
+ 0: \x{200a}\xa0\x{2000}
+
+/[\h\x{dc00}]+/BZSI
+------------------------------------------------------------------
+ Bra
+ [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{dc00}]++
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+ \x{1681}\x{200b}\x{1680}\x{2000}\x{202f}\x{3000}
+ 0: \x{1680}\x{2000}\x{202f}\x{3000}
+ \x{3001}\x{2fff}\x{200a}\xa0\x{2000}
+ 0: \x{200a}\xa0\x{2000}
+
+/\H+/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+ \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f}
+ 0: \x{167f}\x{1681}\x{180d}\x{180f}
+ \x{2000}\x{200a}\x{1fff}\x{200b}
+ 0: \x{1fff}\x{200b}
+ \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060}
+ 0: \x{202e}\x{2030}\x{205e}\x{2060}
+ \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001}
+ 0: \x9f\xa1\x{2fff}\x{3001}
+
+/[\H\x{d800}]+/
+ \x{1680}\x{180e}\x{167f}\x{1681}\x{180d}\x{180f}
+ 0: \x{167f}\x{1681}\x{180d}\x{180f}
+ \x{2000}\x{200a}\x{1fff}\x{200b}
+ 0: \x{1fff}\x{200b}
+ \x{202f}\x{205f}\x{202e}\x{2030}\x{205e}\x{2060}
+ 0: \x{202e}\x{2030}\x{205e}\x{2060}
+ \xa0\x{3000}\x9f\xa1\x{2fff}\x{3001}
+ 0: \x9f\xa1\x{2fff}\x{3001}
+
+/\v+/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+ \x{2027}\x{2030}\x{2028}\x{2029}
+ 0: \x{2028}\x{2029}
+ \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d
+ 0: \x85\x0a\x0b\x0c\x0d
+
+/[\v\x{dc00}]+/BZSI
+------------------------------------------------------------------
+ Bra
+ [\x0a-\x0d\x85\x{2028}-\x{2029}\x{dc00}]++
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+ \x{2027}\x{2030}\x{2028}\x{2029}
+ 0: \x{2028}\x{2029}
+ \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d
+ 0: \x85\x0a\x0b\x0c\x0d
+
+/\V+/SI
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+ \x{2028}\x{2029}\x{2027}\x{2030}
+ 0: \x{2027}\x{2030}
+ \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86
+ 0: \x09\x0e\x84\x86
+
+/[\V\x{d800}]+/
+ \x{2028}\x{2029}\x{2027}\x{2030}
+ 0: \x{2027}\x{2030}
+ \x85\x0a\x0b\x0c\x0d\x09\x0e\x84\x86
+ 0: \x09\x0e\x84\x86
+
+/\R+/SI<bsr_unicode>
+Capturing subpattern count = 0
+Options: bsr_unicode
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+ \x{2027}\x{2030}\x{2028}\x{2029}
+ 0: \x{2028}\x{2029}
+ \x09\x0e\x84\x86\x85\x0a\x0b\x0c\x0d
+ 0: \x85\x0a\x0b\x0c\x0d
+
+/\x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00}/I
+Capturing subpattern count = 0
+No options
+First char = \x{d800}
+Need char = \x{dd00}
+ \x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00}
+ 0: \x{d800}\x{d7ff}\x{dc00}\x{dc00}\x{dcff}\x{dd00}
+
+/[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZ
+------------------------------------------------------------------
+ Bra
+ [^\x80]
+ [^\x{ff}]
+ [^\x{100}]
+ [^\x{1000}]
+ [^\x{ffff}]
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^\x{80}][^\x{ff}][^\x{100}][^\x{1000}][^\x{ffff}]/BZi
+------------------------------------------------------------------
+ Bra
+ /i [^\x80]
+ /i [^\x{ff}]
+ /i [^\x{100}]
+ /i [^\x{1000}]
+ /i [^\x{ffff}]
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZ
+------------------------------------------------------------------
+ Bra
+ [^\x{100}]*
+ [^\x{1000}]+
+ [^\x{ffff}]??
+ [^\x{8000}]{4}
+ [^\x{8000}]*
+ [^\x{7fff}]{2}
+ [^\x{7fff}]{0,7}?
+ [^\x{100}]{5}
+ [^\x{100}]?+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^\x{100}]*[^\x{1000}]+[^\x{ffff}]??[^\x{8000}]{4,}[^\x{7fff}]{2,9}?[^\x{100}]{5,6}+/BZi
+------------------------------------------------------------------
+ Bra
+ /i [^\x{100}]*
+ /i [^\x{1000}]+
+ /i [^\x{ffff}]??
+ /i [^\x{8000}]{4}
+ /i [^\x{8000}]*
+ /i [^\x{7fff}]{2}
+ /i [^\x{7fff}]{0,7}?
+ /i [^\x{100}]{5}
+ /i [^\x{100}]?+
+ Ket
+ End
+------------------------------------------------------------------
+
+/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/K
+ XX
+ 0: XX
+MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF
+
+/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/K
+ XX
+ 0: XX
+MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+
+/\u0100/<JS>BZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+
+/[\u0100-\u0200]/<JS>BZ
+------------------------------------------------------------------
+ Bra
+ [\x{100}-\x{200}]
+ Ket
+ End
+------------------------------------------------------------------
+
+/\ud800/<JS>BZ
+------------------------------------------------------------------
+ Bra
+ \x{d800}
+ Ket
+ End
+------------------------------------------------------------------
+
+/^\x{ffff}+/i
+ \x{ffff}
+ 0: \x{ffff}
+
+/^\x{ffff}?/i
+ \x{ffff}
+ 0: \x{ffff}
+
+/^\x{ffff}*/i
+ \x{ffff}
+ 0: \x{ffff}
+
+/^\x{ffff}{3}/i
+ \x{ffff}\x{ffff}\x{ffff}
+ 0: \x{ffff}\x{ffff}\x{ffff}
+
+/^\x{ffff}{0,3}/i
+ \x{ffff}
+ 0: \x{ffff}
+
+/[^\x00-a]{12,}[^b-\xff]*/BZ
+------------------------------------------------------------------
+ Bra
+ [b-\xff] (neg){12,}
+ [\x00-a] (neg)*+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^\s]*\s* [^\W]+\W+ [^\d]*?\d0 [^\d\w]{4,6}?\w*A/BZ
+------------------------------------------------------------------
+ Bra
+ [\x00-\x08\x0e-\x1f!-\xff] (neg)*
+ \s*
+
+ [0-9A-Z_a-z]++
+ \W+
+
+ [\x00-/:-\xff] (neg)*?
+ \d
+ 0
+ [\x00-/:-@[-^`{-\xff] (neg){4,6}?
+ \w*
+ A
+ Ket
+ End
+------------------------------------------------------------------
+
+/a*[b-\x{200}]?a#a*[b-\x{200}]?b#[a-f]*[g-\x{200}]*#[g-\x{200}]*[a-c]*#[g-\x{200}]*[a-h]*/BZ
+------------------------------------------------------------------
+ Bra
+ a*
+ [b-\x{200}]?+
+ a#
+ a*+
+ [b-\x{200}]?
+ b#
+ [a-f]*
+ [g-\x{200}]*+
+ #
+ [g-\x{200}]*
+ [a-c]*+
+ #
+ [g-\x{200}]*
+ [a-h]*+
+ Ket
+ End
+------------------------------------------------------------------
+
+/^[\x{1234}\x{4321}]{2,4}?/
+ \x{1234}\x{1234}\x{1234}
+ 0: \x{1234}\x{1234}
+
+/-- End of testinput17 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput18-16 b/ext/pcre/pcrelib/testdata/testoutput18-16
new file mode 100644
index 0000000000..1ca9ee7401
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput18-16
@@ -0,0 +1,1026 @@
+/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to
+ the 16- and 32-bit libraries. --/
+
+< forbid W
+
+/xxx/8?DZSS
+**Failed: invalid UTF-8 string cannot be converted to UTF-16
+
+/abc/8
+ ]
+**Failed: invalid UTF-8 string cannot be used as input in UTF mode
+
+/X(\C{3})/8
+ X\x{11234}Y
+ 0: X\x{11234}Y
+ 1: \x{11234}Y
+ X\x{11234}YZ
+ 0: X\x{11234}Y
+ 1: \x{11234}Y
+
+/X(\C{4})/8
+ X\x{11234}YZ
+ 0: X\x{11234}YZ
+ 1: \x{11234}YZ
+ X\x{11234}YZW
+ 0: X\x{11234}YZ
+ 1: \x{11234}YZ
+
+/X\C*/8
+ XYZabcdce
+ 0: XYZabcdce
+
+/X\C*?/8
+ XYZabcde
+ 0: X
+
+/X\C{3,5}/8
+ Xabcdefg
+ 0: Xabcde
+ X\x{11234}Y
+ 0: X\x{11234}Y
+ X\x{11234}YZ
+ 0: X\x{11234}YZ
+ X\x{11234}\x{512}
+ 0: X\x{11234}\x{512}
+ X\x{11234}\x{512}YZ
+ 0: X\x{11234}\x{512}YZ
+ X\x{11234}\x{512}\x{11234}Z
+ 0: X\x{11234}\x{512}\x{11234}
+
+/X\C{3,5}?/8
+ Xabcdefg
+ 0: Xabc
+ X\x{11234}Y
+ 0: X\x{11234}Y
+ X\x{11234}YZ
+ 0: X\x{11234}Y
+ X\x{11234}\x{512}YZ
+ 0: X\x{11234}\x{512}
+ *** Failers
+No match
+ X\x{11234}
+No match
+
+/a\Cb/8
+ aXb
+ 0: aXb
+ a\nb
+ 0: a\x{0a}b
+
+/a\C\Cb/8
+ a\x{12257}b
+ 0: a\x{12257}b
+ a\x{12257}\x{11234}b
+No match
+ ** Failers
+No match
+ a\x{100}b
+No match
+
+/ab\Cde/8
+ abXde
+ 0: abXde
+
+/-- Check maximum character size --/
+
+/\x{ffff}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{ffff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{ffff}
+No need char
+
+/\x{10000}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{10000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{d800}
+Need char = \x{dc00}
+
+/\x{100}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+No need char
+
+/\x{1000}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{1000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{1000}
+No need char
+
+/\x{10000}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{10000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{d800}
+Need char = \x{dc00}
+
+/\x{100000}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{dbc0}
+Need char = \x{dc00}
+
+/\x{10ffff}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{10ffff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{dbff}
+Need char = \x{dfff}
+
+/[\x{ff}]/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{ff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{ff}
+No need char
+
+/[\x{100}]/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+No need char
+
+/\x80/8DZ
+------------------------------------------------------------------
+ Bra
+ \x80
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{80}
+No need char
+
+/\xff/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{ff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{ff}
+No need char
+
+/\x{D55c}\x{ad6d}\x{C5B4}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{d55c}\x{ad6d}\x{c5b4}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{d55c}
+Need char = \x{c5b4}
+ \x{D55c}\x{ad6d}\x{C5B4}
+ 0: \x{d55c}\x{ad6d}\x{c5b4}
+
+/\x{65e5}\x{672c}\x{8a9e}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{65e5}\x{672c}\x{8a9e}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{65e5}
+Need char = \x{8a9e}
+ \x{65e5}\x{672c}\x{8a9e}
+ 0: \x{65e5}\x{672c}\x{8a9e}
+
+/\x{80}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x80
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{80}
+No need char
+
+/\x{084}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{84}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{84}
+No need char
+
+/\x{104}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{104}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{104}
+No need char
+
+/\x{861}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{861}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{861}
+No need char
+
+/\x{212ab}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{212ab}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{d844}
+Need char = \x{deab}
+
+/-- This one is here not because it's different to Perl, but because the way
+the captured single-byte is displayed. (In Perl it becomes a character, and you
+can't tell the difference.) --/
+
+/X(\C)(.*)/8
+ X\x{1234}
+ 0: X\x{1234}
+ 1: \x{1234}
+ 2:
+ X\nabc
+ 0: X\x{0a}abc
+ 1: \x{0a}
+ 2: abc
+
+/-- This one is here because Perl gives out a grumbly error message (quite
+correctly, but that messes up comparisons). --/
+
+/a\Cb/8
+ *** Failers
+No match
+ a\x{100}b
+ 0: a\x{100}b
+
+/[^ab\xC0-\xF0]/8SDZ
+------------------------------------------------------------------
+ Bra
+ [\x00-`c-\xbf\xf1-\xff] (neg)
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
+ \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19
+ \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4
+ 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y
+ Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f
+ \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e
+ \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d
+ \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac
+ \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb
+ \xbc \xbd \xbe \xbf \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb
+ \xfc \xfd \xfe \xff
+ \x{f1}
+ 0: \x{f1}
+ \x{bf}
+ 0: \x{bf}
+ \x{100}
+ 0: \x{100}
+ \x{1000}
+ 0: \x{1000}
+ *** Failers
+ 0: *
+ \x{c0}
+No match
+ \x{f0}
+No match
+
+/Ā{3,4}/8SDZ
+------------------------------------------------------------------
+ Bra
+ \x{100}{3}
+ \x{100}?+
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+Need char = \x{100}
+Subject length lower bound = 3
+No set of starting bytes
+ \x{100}\x{100}\x{100}\x{100\x{100}
+ 0: \x{100}\x{100}\x{100}
+
+/(\x{100}+|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}++
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: x \xff
+
+/(\x{100}*a|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}*+
+ a
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: a x \xff
+
+/(\x{100}{0,2}a|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}{0,2}+
+ a
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: a x \xff
+
+/(\x{100}{1,2}a|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}
+ \x{100}{0,1}+
+ a
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: x \xff
+
+/\x{100}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+No need char
+
+/a\x{100}\x{101}*/8DZ
+------------------------------------------------------------------
+ Bra
+ a\x{100}
+ \x{101}*+
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'a'
+Need char = \x{100}
+
+/a\x{100}\x{101}+/8DZ
+------------------------------------------------------------------
+ Bra
+ a\x{100}
+ \x{101}++
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'a'
+Need char = \x{101}
+
+/[^\x{c4}]/DZ
+------------------------------------------------------------------
+ Bra
+ [^\x{c4}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/[\x{100}]/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+No need char
+ \x{100}
+ 0: \x{100}
+ Z\x{100}
+ 0: \x{100}
+ \x{100}Z
+ 0: \x{100}
+ *** Failers
+No match
+
+/[\xff]/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{ff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{ff}
+No need char
+ >\x{ff}<
+ 0: \x{ff}
+
+/[^\xff]/8DZ
+------------------------------------------------------------------
+ Bra
+ [^\x{ff}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+
+/\x{100}abc(xyz(?1))/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}abc
+ CBra 1
+ xyz
+ Recurse
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+First char = \x{100}
+Need char = 'z'
+
+/\777/8I
+Capturing subpattern count = 0
+Options: utf
+First char = \x{1ff}
+No need char
+ \x{1ff}
+ 0: \x{1ff}
+ \777
+ 0: \x{1ff}
+
+/\x{100}+\x{200}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}++
+ \x{200}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+Need char = \x{200}
+
+/\x{100}+X/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}++
+ X
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+Need char = 'X'
+
+/^[\QĀ\E-\QŐ\E/BZ8
+Failed: missing terminating ] for character class at offset 13
+
+/X/8
+ \x{d800}
+Error -10 (bad UTF-16 string) offset=0 reason=1
+ \x{d800}\?
+No match
+ \x{da00}
+Error -10 (bad UTF-16 string) offset=0 reason=1
+ \x{da00}\?
+No match
+ \x{dc00}
+Error -10 (bad UTF-16 string) offset=0 reason=3
+ \x{dc00}\?
+No match
+ \x{de00}
+Error -10 (bad UTF-16 string) offset=0 reason=3
+ \x{de00}\?
+No match
+ \x{dfff}
+Error -10 (bad UTF-16 string) offset=0 reason=3
+ \x{dfff}\?
+No match
+ \x{110000}
+** Failed: character \x{110000} is greater than 0x10ffff and so cannot be converted to UTF-16
+ \x{d800}\x{1234}
+Error -10 (bad UTF-16 string) offset=1 reason=2
+
+/(*UTF16)\x{11234}/
+ abcd\x{11234}pqr
+ 0: \x{11234}
+
+/(*UTF)\x{11234}/I
+Capturing subpattern count = 0
+Options: utf
+First char = \x{d804}
+Need char = \x{de34}
+ abcd\x{11234}pqr
+ 0: \x{11234}
+
+/(*UTF-32)\x{11234}/
+Failed: (*VERB) not recognized or malformed at offset 5
+
+/(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I
+Capturing subpattern count = 0
+Options: bsr_unicode utf
+Forced newline sequence: CRLF
+First char = 'a'
+Need char = 'b'
+
+/(*CRLF)(*UTF32)(*BSR_UNICODE)a\Rb/I
+Failed: (*VERB) not recognized or malformed at offset 12
+
+/\h/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x09 \x20 \xa0 \xff
+ ABC\x{09}
+ 0: \x{09}
+ ABC\x{20}
+ 0:
+ ABC\x{a0}
+ 0: \x{a0}
+ ABC\x{1680}
+ 0: \x{1680}
+ ABC\x{180e}
+ 0: \x{180e}
+ ABC\x{2000}
+ 0: \x{2000}
+ ABC\x{202f}
+ 0: \x{202f}
+ ABC\x{205f}
+ 0: \x{205f}
+ ABC\x{3000}
+ 0: \x{3000}
+
+/\v/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+ ABC\x{0a}
+ 0: \x{0a}
+ ABC\x{0b}
+ 0: \x{0b}
+ ABC\x{0c}
+ 0: \x{0c}
+ ABC\x{0d}
+ 0: \x{0d}
+ ABC\x{85}
+ 0: \x{85}
+ ABC\x{2028}
+ 0: \x{2028}
+
+/\h*A/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'A'
+Subject length lower bound = 1
+Starting byte set: \x09 \x20 A \xa0 \xff
+ CDBABC
+ 0: A
+ \x{2000}ABC
+ 0: \x{2000}A
+
+/\R*A/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'A'
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d A \x85 \xff
+ CDBABC
+ 0: A
+ \x{2028}A
+ 0: \x{2028}A
+
+/\v+A/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'A'
+Subject length lower bound = 2
+Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+
+/\s?xxx\s/8SI
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'x'
+Subject length lower bound = 4
+Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 x
+
+/\sxxx\s/I8ST1
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'x'
+Subject length lower bound = 5
+Starting byte set: \x09 \x0a \x0c \x0d \x20 \x85 \xa0
+ AB\x{85}xxx\x{a0}XYZ
+ 0: \x{85}xxx\x{a0}
+ AB\x{a0}xxx\x{85}XYZ
+ 0: \x{a0}xxx\x{85}
+
+/\S \S/I8ST1
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = ' '
+Subject length lower bound = 3
+Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e
+ \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d
+ \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @
+ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e
+ f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 \x83
+ \x84 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93
+ \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa1 \xa2 \xa3
+ \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2
+ \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xc0 \xc1
+ \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0
+ \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf
+ \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee
+ \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd
+ \xfe \xff
+ \x{a2} \x{84}
+ 0: \x{a2} \x{84}
+ A Z
+ 0: A Z
+
+/a+/8
+ a\x{123}aa\>1
+ 0: aa
+ a\x{123}aa\>2
+ 0: aa
+ a\x{123}aa\>3
+ 0: a
+ a\x{123}aa\>4
+No match
+ a\x{123}aa\>5
+Error -24 (bad offset value)
+ a\x{123}aa\>6
+Error -24 (bad offset value)
+
+/\x{1234}+/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+First char = \x{1234}
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/\x{1234}+?/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+First char = \x{1234}
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/\x{1234}++/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+First char = \x{1234}
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/\x{1234}{2}/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+First char = \x{1234}
+Need char = \x{1234}
+Subject length lower bound = 2
+No set of starting bytes
+
+/[^\x{c4}]/8DZ
+------------------------------------------------------------------
+ Bra
+ [^\x{c4}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+
+/X+\x{200}/8DZ
+------------------------------------------------------------------
+ Bra
+ X++
+ \x{200}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'X'
+Need char = \x{200}
+
+/\R/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+
+/-- Check bad offset --/
+
+/a/8
+ \x{10000}\>1
+Error -11 (bad UTF-16 offset)
+ \x{10000}ab\>1
+Error -11 (bad UTF-16 offset)
+ \x{10000}ab\>2
+ 0: a
+ \x{10000}ab\>3
+No match
+ \x{10000}ab\>4
+No match
+ \x{10000}ab\>5
+Error -24 (bad offset value)
+
+//8
+Failed: invalid UTF-16 string at offset 0
+
+/\w+\x{C4}/8BZ
+------------------------------------------------------------------
+ Bra
+ \w++
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ a\x{C4}\x{C4}
+ 0: a\x{c4}
+
+/\w+\x{C4}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \w+
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ a\x{C4}\x{C4}
+ 0: a\x{c4}\x{c4}
+
+/\W+\x{C4}/8BZ
+------------------------------------------------------------------
+ Bra
+ \W+
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{C4}
+ 0: !\x{c4}
+
+/\W+\x{C4}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \W++
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{C4}
+ 0: !\x{c4}
+
+/\W+\x{A1}/8BZ
+------------------------------------------------------------------
+ Bra
+ \W+
+ \x{a1}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{A1}
+ 0: !\x{a1}
+
+/\W+\x{A1}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \W+
+ \x{a1}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{A1}
+ 0: !\x{a1}
+
+/X\s+\x{A0}/8BZ
+------------------------------------------------------------------
+ Bra
+ X
+ \s++
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x20\x{A0}\x{A0}
+ 0: X \x{a0}
+
+/X\s+\x{A0}/8BZT1
+------------------------------------------------------------------
+ Bra
+ X
+ \s+
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x20\x{A0}\x{A0}
+ 0: X \x{a0}\x{a0}
+
+/\S+\x{A0}/8BZ
+------------------------------------------------------------------
+ Bra
+ \S+
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x{A0}\x{A0}
+ 0: X\x{a0}\x{a0}
+
+/\S+\x{A0}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \S++
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x{A0}\x{A0}
+ 0: X\x{a0}
+
+/\x{a0}+\s!/8BZ
+------------------------------------------------------------------
+ Bra
+ \x{a0}++
+ \s
+ !
+ Ket
+ End
+------------------------------------------------------------------
+ \x{a0}\x20!
+ 0: \x{a0} !
+
+/\x{a0}+\s!/8BZT1
+------------------------------------------------------------------
+ Bra
+ \x{a0}+
+ \s
+ !
+ Ket
+ End
+------------------------------------------------------------------
+ \x{a0}\x20!
+ 0: \x{a0} !
+
+/(*UTF)abc/9
+Failed: setting UTF is disabled by the application at offset 0
+
+/abc/89
+Failed: setting UTF is disabled by the application at offset 0
+
+/-- End of testinput18 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput18-32 b/ext/pcre/pcrelib/testdata/testoutput18-32
new file mode 100644
index 0000000000..89be3a4b05
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput18-32
@@ -0,0 +1,1023 @@
+/-- This set of tests is for UTF-16 and UTF-32 support, and is relevant only to
+ the 16- and 32-bit libraries. --/
+
+< forbid W
+
+/xxx/8?DZSS
+**Failed: invalid UTF-8 string cannot be converted to UTF-32
+
+/abc/8
+ ]
+**Failed: invalid UTF-8 string cannot be used as input in UTF mode
+
+/X(\C{3})/8
+ X\x{11234}Y
+No match
+ X\x{11234}YZ
+ 0: X\x{11234}YZ
+ 1: \x{11234}YZ
+
+/X(\C{4})/8
+ X\x{11234}YZ
+No match
+ X\x{11234}YZW
+ 0: X\x{11234}YZW
+ 1: \x{11234}YZW
+
+/X\C*/8
+ XYZabcdce
+ 0: XYZabcdce
+
+/X\C*?/8
+ XYZabcde
+ 0: X
+
+/X\C{3,5}/8
+ Xabcdefg
+ 0: Xabcde
+ X\x{11234}Y
+No match
+ X\x{11234}YZ
+ 0: X\x{11234}YZ
+ X\x{11234}\x{512}
+No match
+ X\x{11234}\x{512}YZ
+ 0: X\x{11234}\x{512}YZ
+ X\x{11234}\x{512}\x{11234}Z
+ 0: X\x{11234}\x{512}\x{11234}Z
+
+/X\C{3,5}?/8
+ Xabcdefg
+ 0: Xabc
+ X\x{11234}Y
+No match
+ X\x{11234}YZ
+ 0: X\x{11234}YZ
+ X\x{11234}\x{512}YZ
+ 0: X\x{11234}\x{512}Y
+ *** Failers
+No match
+ X\x{11234}
+No match
+
+/a\Cb/8
+ aXb
+ 0: aXb
+ a\nb
+ 0: a\x{0a}b
+
+/a\C\Cb/8
+ a\x{12257}b
+No match
+ a\x{12257}\x{11234}b
+ 0: a\x{12257}\x{11234}b
+ ** Failers
+No match
+ a\x{100}b
+No match
+
+/ab\Cde/8
+ abXde
+ 0: abXde
+
+/-- Check maximum character size --/
+
+/\x{ffff}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{ffff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{ffff}
+No need char
+
+/\x{10000}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{10000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{10000}
+No need char
+
+/\x{100}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+No need char
+
+/\x{1000}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{1000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{1000}
+No need char
+
+/\x{10000}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{10000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{10000}
+No need char
+
+/\x{100000}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100000}
+No need char
+
+/\x{10ffff}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{10ffff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{10ffff}
+No need char
+
+/[\x{ff}]/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{ff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{ff}
+No need char
+
+/[\x{100}]/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+No need char
+
+/\x80/8DZ
+------------------------------------------------------------------
+ Bra
+ \x80
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{80}
+No need char
+
+/\xff/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{ff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{ff}
+No need char
+
+/\x{D55c}\x{ad6d}\x{C5B4}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{d55c}\x{ad6d}\x{c5b4}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{d55c}
+Need char = \x{c5b4}
+ \x{D55c}\x{ad6d}\x{C5B4}
+ 0: \x{d55c}\x{ad6d}\x{c5b4}
+
+/\x{65e5}\x{672c}\x{8a9e}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{65e5}\x{672c}\x{8a9e}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{65e5}
+Need char = \x{8a9e}
+ \x{65e5}\x{672c}\x{8a9e}
+ 0: \x{65e5}\x{672c}\x{8a9e}
+
+/\x{80}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x80
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{80}
+No need char
+
+/\x{084}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{84}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{84}
+No need char
+
+/\x{104}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{104}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{104}
+No need char
+
+/\x{861}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{861}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{861}
+No need char
+
+/\x{212ab}/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{212ab}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{212ab}
+No need char
+
+/-- This one is here not because it's different to Perl, but because the way
+the captured single-byte is displayed. (In Perl it becomes a character, and you
+can't tell the difference.) --/
+
+/X(\C)(.*)/8
+ X\x{1234}
+ 0: X\x{1234}
+ 1: \x{1234}
+ 2:
+ X\nabc
+ 0: X\x{0a}abc
+ 1: \x{0a}
+ 2: abc
+
+/-- This one is here because Perl gives out a grumbly error message (quite
+correctly, but that messes up comparisons). --/
+
+/a\Cb/8
+ *** Failers
+No match
+ a\x{100}b
+ 0: a\x{100}b
+
+/[^ab\xC0-\xF0]/8SDZ
+------------------------------------------------------------------
+ Bra
+ [\x00-`c-\xbf\xf1-\xff] (neg)
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a
+ \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19
+ \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4
+ 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y
+ Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f
+ \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e
+ \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d
+ \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac
+ \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb
+ \xbc \xbd \xbe \xbf \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb
+ \xfc \xfd \xfe \xff
+ \x{f1}
+ 0: \x{f1}
+ \x{bf}
+ 0: \x{bf}
+ \x{100}
+ 0: \x{100}
+ \x{1000}
+ 0: \x{1000}
+ *** Failers
+ 0: *
+ \x{c0}
+No match
+ \x{f0}
+No match
+
+/Ā{3,4}/8SDZ
+------------------------------------------------------------------
+ Bra
+ \x{100}{3}
+ \x{100}?+
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+Need char = \x{100}
+Subject length lower bound = 3
+No set of starting bytes
+ \x{100}\x{100}\x{100}\x{100\x{100}
+ 0: \x{100}\x{100}\x{100}
+
+/(\x{100}+|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}++
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: x \xff
+
+/(\x{100}*a|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}*+
+ a
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: a x \xff
+
+/(\x{100}{0,2}a|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}{0,2}+
+ a
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: a x \xff
+
+/(\x{100}{1,2}a|x)/8SDZ
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ \x{100}
+ \x{100}{0,1}+
+ a
+ Alt
+ x
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: x \xff
+
+/\x{100}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+No need char
+
+/a\x{100}\x{101}*/8DZ
+------------------------------------------------------------------
+ Bra
+ a\x{100}
+ \x{101}*+
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'a'
+Need char = \x{100}
+
+/a\x{100}\x{101}+/8DZ
+------------------------------------------------------------------
+ Bra
+ a\x{100}
+ \x{101}++
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'a'
+Need char = \x{101}
+
+/[^\x{c4}]/DZ
+------------------------------------------------------------------
+ Bra
+ [^\x{c4}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/[\x{100}]/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+No need char
+ \x{100}
+ 0: \x{100}
+ Z\x{100}
+ 0: \x{100}
+ \x{100}Z
+ 0: \x{100}
+ *** Failers
+No match
+
+/[\xff]/DZ8
+------------------------------------------------------------------
+ Bra
+ \x{ff}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{ff}
+No need char
+ >\x{ff}<
+ 0: \x{ff}
+
+/[^\xff]/8DZ
+------------------------------------------------------------------
+ Bra
+ [^\x{ff}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+
+/\x{100}abc(xyz(?1))/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}abc
+ CBra 1
+ xyz
+ Recurse
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: utf
+First char = \x{100}
+Need char = 'z'
+
+/\777/8I
+Capturing subpattern count = 0
+Options: utf
+First char = \x{1ff}
+No need char
+ \x{1ff}
+ 0: \x{1ff}
+ \777
+ 0: \x{1ff}
+
+/\x{100}+\x{200}/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}++
+ \x{200}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+Need char = \x{200}
+
+/\x{100}+X/8DZ
+------------------------------------------------------------------
+ Bra
+ \x{100}++
+ X
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = \x{100}
+Need char = 'X'
+
+/^[\QĀ\E-\QŐ\E/BZ8
+Failed: missing terminating ] for character class at offset 13
+
+/X/8
+ \x{d800}
+Error -10 (bad UTF-32 string) offset=0 reason=1
+ \x{d800}\?
+No match
+ \x{da00}
+Error -10 (bad UTF-32 string) offset=0 reason=1
+ \x{da00}\?
+No match
+ \x{dc00}
+Error -10 (bad UTF-32 string) offset=0 reason=1
+ \x{dc00}\?
+No match
+ \x{de00}
+Error -10 (bad UTF-32 string) offset=0 reason=1
+ \x{de00}\?
+No match
+ \x{dfff}
+Error -10 (bad UTF-32 string) offset=0 reason=1
+ \x{dfff}\?
+No match
+ \x{110000}
+Error -10 (bad UTF-32 string) offset=0 reason=3
+ \x{d800}\x{1234}
+Error -10 (bad UTF-32 string) offset=0 reason=1
+
+/(*UTF16)\x{11234}/
+Failed: (*VERB) not recognized or malformed at offset 5
+
+/(*UTF)\x{11234}/I
+Capturing subpattern count = 0
+Options: utf
+First char = \x{11234}
+No need char
+ abcd\x{11234}pqr
+ 0: \x{11234}
+
+/(*UTF-32)\x{11234}/
+Failed: (*VERB) not recognized or malformed at offset 5
+
+/(*CRLF)(*UTF16)(*BSR_UNICODE)a\Rb/I
+Failed: (*VERB) not recognized or malformed at offset 12
+
+/(*CRLF)(*UTF32)(*BSR_UNICODE)a\Rb/I
+Capturing subpattern count = 0
+Options: bsr_unicode utf
+Forced newline sequence: CRLF
+First char = 'a'
+Need char = 'b'
+
+/\h/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x09 \x20 \xa0 \xff
+ ABC\x{09}
+ 0: \x{09}
+ ABC\x{20}
+ 0:
+ ABC\x{a0}
+ 0: \x{a0}
+ ABC\x{1680}
+ 0: \x{1680}
+ ABC\x{180e}
+ 0: \x{180e}
+ ABC\x{2000}
+ 0: \x{2000}
+ ABC\x{202f}
+ 0: \x{202f}
+ ABC\x{205f}
+ 0: \x{205f}
+ ABC\x{3000}
+ 0: \x{3000}
+
+/\v/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+ ABC\x{0a}
+ 0: \x{0a}
+ ABC\x{0b}
+ 0: \x{0b}
+ ABC\x{0c}
+ 0: \x{0c}
+ ABC\x{0d}
+ 0: \x{0d}
+ ABC\x{85}
+ 0: \x{85}
+ ABC\x{2028}
+ 0: \x{2028}
+
+/\h*A/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'A'
+Subject length lower bound = 1
+Starting byte set: \x09 \x20 A \xa0 \xff
+ CDBABC
+ 0: A
+ \x{2000}ABC
+ 0: \x{2000}A
+
+/\R*A/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'A'
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d A \x85 \xff
+ CDBABC
+ 0: A
+ \x{2028}A
+ 0: \x{2028}A
+
+/\v+A/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'A'
+Subject length lower bound = 2
+Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+
+/\s?xxx\s/8SI
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'x'
+Subject length lower bound = 4
+Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 x
+
+/\sxxx\s/I8ST1
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = 'x'
+Subject length lower bound = 5
+Starting byte set: \x09 \x0a \x0c \x0d \x20 \x85 \xa0
+ AB\x{85}xxx\x{a0}XYZ
+ 0: \x{85}xxx\x{a0}
+ AB\x{a0}xxx\x{85}XYZ
+ 0: \x{a0}xxx\x{85}
+
+/\S \S/I8ST1
+Capturing subpattern count = 0
+Options: utf
+No first char
+Need char = ' '
+Subject length lower bound = 3
+Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x0b \x0e
+ \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d
+ \x1e \x1f ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @
+ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e
+ f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 \x83
+ \x84 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93
+ \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa1 \xa2 \xa3
+ \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2
+ \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xc0 \xc1
+ \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0
+ \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf
+ \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee
+ \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd
+ \xfe \xff
+ \x{a2} \x{84}
+ 0: \x{a2} \x{84}
+ A Z
+ 0: A Z
+
+/a+/8
+ a\x{123}aa\>1
+ 0: aa
+ a\x{123}aa\>2
+ 0: aa
+ a\x{123}aa\>3
+ 0: a
+ a\x{123}aa\>4
+No match
+ a\x{123}aa\>5
+Error -24 (bad offset value)
+ a\x{123}aa\>6
+Error -24 (bad offset value)
+
+/\x{1234}+/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+First char = \x{1234}
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/\x{1234}+?/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+First char = \x{1234}
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/\x{1234}++/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+First char = \x{1234}
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/\x{1234}{2}/iS8I
+Capturing subpattern count = 0
+Options: caseless utf
+First char = \x{1234}
+Need char = \x{1234}
+Subject length lower bound = 2
+No set of starting bytes
+
+/[^\x{c4}]/8DZ
+------------------------------------------------------------------
+ Bra
+ [^\x{c4}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+
+/X+\x{200}/8DZ
+------------------------------------------------------------------
+ Bra
+ X++
+ \x{200}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'X'
+Need char = \x{200}
+
+/\R/SI8
+Capturing subpattern count = 0
+Options: utf
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: \x0a \x0b \x0c \x0d \x85 \xff
+
+/-- Check bad offset --/
+
+/a/8
+ \x{10000}\>1
+No match
+ \x{10000}ab\>1
+ 0: a
+ \x{10000}ab\>2
+No match
+ \x{10000}ab\>3
+No match
+ \x{10000}ab\>4
+Error -24 (bad offset value)
+ \x{10000}ab\>5
+Error -24 (bad offset value)
+
+//8
+**Failed: character value is ill-formed UTF-32
+
+/\w+\x{C4}/8BZ
+------------------------------------------------------------------
+ Bra
+ \w++
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ a\x{C4}\x{C4}
+ 0: a\x{c4}
+
+/\w+\x{C4}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \w+
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ a\x{C4}\x{C4}
+ 0: a\x{c4}\x{c4}
+
+/\W+\x{C4}/8BZ
+------------------------------------------------------------------
+ Bra
+ \W+
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{C4}
+ 0: !\x{c4}
+
+/\W+\x{C4}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \W++
+ \x{c4}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{C4}
+ 0: !\x{c4}
+
+/\W+\x{A1}/8BZ
+------------------------------------------------------------------
+ Bra
+ \W+
+ \x{a1}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{A1}
+ 0: !\x{a1}
+
+/\W+\x{A1}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \W+
+ \x{a1}
+ Ket
+ End
+------------------------------------------------------------------
+ !\x{A1}
+ 0: !\x{a1}
+
+/X\s+\x{A0}/8BZ
+------------------------------------------------------------------
+ Bra
+ X
+ \s++
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x20\x{A0}\x{A0}
+ 0: X \x{a0}
+
+/X\s+\x{A0}/8BZT1
+------------------------------------------------------------------
+ Bra
+ X
+ \s+
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x20\x{A0}\x{A0}
+ 0: X \x{a0}\x{a0}
+
+/\S+\x{A0}/8BZ
+------------------------------------------------------------------
+ Bra
+ \S+
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x{A0}\x{A0}
+ 0: X\x{a0}\x{a0}
+
+/\S+\x{A0}/8BZT1
+------------------------------------------------------------------
+ Bra
+ \S++
+ \x{a0}
+ Ket
+ End
+------------------------------------------------------------------
+ X\x{A0}\x{A0}
+ 0: X\x{a0}
+
+/\x{a0}+\s!/8BZ
+------------------------------------------------------------------
+ Bra
+ \x{a0}++
+ \s
+ !
+ Ket
+ End
+------------------------------------------------------------------
+ \x{a0}\x20!
+ 0: \x{a0} !
+
+/\x{a0}+\s!/8BZT1
+------------------------------------------------------------------
+ Bra
+ \x{a0}+
+ \s
+ !
+ Ket
+ End
+------------------------------------------------------------------
+ \x{a0}\x20!
+ 0: \x{a0} !
+
+/(*UTF)abc/9
+Failed: setting UTF is disabled by the application at offset 0
+
+/abc/89
+Failed: setting UTF is disabled by the application at offset 0
+
+/-- End of testinput18 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput19 b/ext/pcre/pcrelib/testdata/testoutput19
new file mode 100644
index 0000000000..ccc198cc15
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput19
@@ -0,0 +1,88 @@
+/-- This set of tests is for Unicode property support, relevant only to the
+ 16- and 32-bit library. --/
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8iDZ
+------------------------------------------------------------------
+ Bra
+ /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: caseless utf
+First char = 'A' (caseless)
+Need char = \x{1fb0} (caseless)
+
+/A\x{391}\x{10427}\x{ff3a}\x{1fb0}/8DZ
+------------------------------------------------------------------
+ Bra
+ A\x{391}\x{10427}\x{ff3a}\x{1fb0}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'A'
+Need char = \x{1fb0}
+
+/AB\x{1fb0}/8DZ
+------------------------------------------------------------------
+ Bra
+ AB\x{1fb0}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: utf
+First char = 'A'
+Need char = \x{1fb0}
+
+/AB\x{1fb0}/8DZi
+------------------------------------------------------------------
+ Bra
+ /i AB\x{1fb0}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: caseless utf
+First char = 'A' (caseless)
+Need char = \x{1fb0} (caseless)
+
+/\x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}/8iSI
+Capturing subpattern count = 0
+Options: caseless utf
+First char = \x{401} (caseless)
+Need char = \x{42f} (caseless)
+Subject length lower bound = 17
+No set of starting bytes
+ \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}
+ 0: \x{401}\x{420}\x{421}\x{422}\x{423}\x{424}\x{425}\x{426}\x{427}\x{428}\x{429}\x{42a}\x{42b}\x{42c}\x{42d}\x{42e}\x{42f}
+ \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f}
+ 0: \x{451}\x{440}\x{441}\x{442}\x{443}\x{444}\x{445}\x{446}\x{447}\x{448}\x{449}\x{44a}\x{44b}\x{44c}\x{44d}\x{44e}\x{44f}
+
+/[ⱥ]/8iBZ
+------------------------------------------------------------------
+ Bra
+ /i \x{2c65}
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^ⱥ]/8iBZ
+------------------------------------------------------------------
+ Bra
+ /i [^\x{2c65}]
+ Ket
+ End
+------------------------------------------------------------------
+
+/[[:blank:]]/WBZ
+------------------------------------------------------------------
+ Bra
+ [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]
+ Ket
+ End
+------------------------------------------------------------------
+
+/-- End of testinput19 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput2 b/ext/pcre/pcrelib/testdata/testoutput2
index e9cddf80d1..844497abcd 100644
--- a/ext/pcre/pcrelib/testdata/testoutput2
+++ b/ext/pcre/pcrelib/testdata/testoutput2
@@ -7,9 +7,12 @@
NOTE: This is a non-UTF set of tests. When UTF support is needed, use
test 5, and if Unicode Property Support is needed, use test 7. --/
+
+< forbid 8W
/(a)b|/I
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
@@ -228,7 +231,7 @@ No options
No first char
No need char
Subject length lower bound = 1
-Starting byte set: \x09 \x0a \x0c \x0d \x20 a b
+Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 a b
/(ab\2)/
Failed: reference to non-existent subpattern at offset 6
@@ -448,10 +451,10 @@ Need char = '='
/(?<!bar|cattle)foo/I
Capturing subpattern count = 0
+Max lookbehind = 6
No options
First char = 'f'
Need char = 'o'
-Max lookbehind = 6
foo
0: foo
catfoo
@@ -498,6 +501,7 @@ No need char
/(?s).*/I
Capturing subpattern count = 0
+May match empty string
Options: anchored dotall
No first char
No need char
@@ -545,10 +549,10 @@ Failed: conditional group contains more than two branches at offset 13
Failed: conditional group contains more than two branches at offset 12
/(?(1a)/
-Failed: missing ) at offset 6
+Failed: malformed number or name after (?( at offset 4
/(?(1a))/
-Failed: reference to non-existent subpattern at offset 6
+Failed: malformed number or name after (?( at offset 4
/(?(?i))/
Failed: assertion expected after (?( at offset 3
@@ -631,6 +635,7 @@ No match
/\Aabc/Im
Capturing subpattern count = 0
+Max lookbehind = 1
Options: anchored multiline
No first char
No need char
@@ -656,19 +661,19 @@ No need char
/(?<=foo)[ab]/IS
Capturing subpattern count = 0
+Max lookbehind = 3
No options
No first char
No need char
-Max lookbehind = 3
Subject length lower bound = 1
Starting byte set: a b
/(?<!foo)(alpha|omega)/IS
Capturing subpattern count = 1
+Max lookbehind = 3
No options
No first char
Need char = 'a'
-Max lookbehind = 3
Subject length lower bound = 5
Starting byte set: a o
@@ -682,11 +687,11 @@ Starting byte set: a b
/(?<=foo\n)^bar/Im
Capturing subpattern count = 0
+Max lookbehind = 4
Contains explicit CR or LF match
Options: multiline
No first char
Need char = 'r'
-Max lookbehind = 4
foo\nbarbar
0: bar
***Failers
@@ -700,11 +705,11 @@ No match
/^(?<=foo\n)bar/Im
Capturing subpattern count = 0
+Max lookbehind = 4
Contains explicit CR or LF match
Options: multiline
First char at start or follows newline
Need char = 'r'
-Max lookbehind = 4
foo\nbarbar
0: bar
***Failers
@@ -743,10 +748,10 @@ Failed: lookbehind assertion is not fixed length at offset 13
/(?<=bullock|donkey)-cart/I
Capturing subpattern count = 0
+Max lookbehind = 7
No options
First char = '-'
Need char = 't'
-Max lookbehind = 7
the bullock-cart
0: -cart
a donkey-cart race
@@ -760,17 +765,19 @@ No match
/(?<=ab(?i)x|y|z)/I
Capturing subpattern count = 0
+Max lookbehind = 3
+May match empty string
No options
No first char
No need char
-Max lookbehind = 3
/(?>.*)(?<=(abcd)|(xyz))/I
Capturing subpattern count = 2
+Max lookbehind = 4
+May match empty string
No options
No first char
No need char
-Max lookbehind = 4
alphabetabcd
0: alphabetabcd
1: abcd
@@ -781,10 +788,10 @@ Max lookbehind = 4
/(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/I
Capturing subpattern count = 0
+Max lookbehind = 4
No options
First char = 'Z'
Need char = 'Z'
-Max lookbehind = 4
abxyZZ
0: ZZ
abXyZZ
@@ -810,10 +817,10 @@ No match
/(?<!(foo)a)bar/I
Capturing subpattern count = 1
+Max lookbehind = 4
No options
First char = 'b'
Need char = 'r'
-Max lookbehind = 4
bar
0: bar
foobbar
@@ -823,22 +830,6 @@ No match
fooabar
No match
-/This one is here because Perl 5.005_02 doesn't fail it/I
-Capturing subpattern count = 0
-No options
-First char = 'T'
-Need char = 't'
-
-/^(a)?(?(1)a|b)+$/I
-Capturing subpattern count = 1
-Options: anchored
-No first char
-No need char
- *** Failers
-No match
- a
-No match
-
/This one is here because Perl behaves differently; see also the following/I
Capturing subpattern count = 0
No options
@@ -1212,10 +1203,10 @@ No need char
/\Biss\B/I+
Capturing subpattern count = 0
+Max lookbehind = 1
No options
First char = 'i'
Need char = 's'
-Max lookbehind = 1
Mississippi
0: iss
0+ issippi
@@ -1233,20 +1224,20 @@ Need char = 's'
/\Biss\B/IG+
Capturing subpattern count = 0
+Max lookbehind = 1
No options
First char = 'i'
Need char = 's'
-Max lookbehind = 1
Mississippi
0: iss
0+ issippi
/\Biss\B/Ig+
Capturing subpattern count = 0
+Max lookbehind = 1
No options
First char = 'i'
Need char = 's'
-Max lookbehind = 1
Mississippi
0: iss
0+ issippi
@@ -1259,10 +1250,10 @@ No match
/(?<=[Ms])iss/Ig+
Capturing subpattern count = 0
+Max lookbehind = 1
No options
First char = 'i'
Need char = 's'
-Max lookbehind = 1
Mississippi
0: iss
0+ issippi
@@ -1271,10 +1262,10 @@ Max lookbehind = 1
/(?<=[Ms])iss/IG+
Capturing subpattern count = 0
+Max lookbehind = 1
No options
First char = 'i'
Need char = 's'
-Max lookbehind = 1
Mississippi
0: iss
0+ issippi
@@ -1392,6 +1383,7 @@ Need char = 'c'
/a*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -1410,6 +1402,7 @@ Need char = 'a'
/a{0,3}/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -1452,10 +1445,10 @@ Need char = 'r'
/...(?<=abc)/I
Capturing subpattern count = 0
+Max lookbehind = 3
No options
No first char
No need char
-Max lookbehind = 3
/abc(?!pqr)/I
Capturing subpattern count = 0
@@ -1609,6 +1602,7 @@ Need char = 'e'
/a?b?/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -1627,6 +1621,7 @@ No match
/|-/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -2640,6 +2635,7 @@ Need char = '-'
End
------------------------------------------------------------------
Capturing subpattern count = 0
+May match empty string
Options: extended
No first char
No need char
@@ -2659,7 +2655,7 @@ No need char
/[\s]/DZ
------------------------------------------------------------------
Bra
- [\x09\x0a\x0c\x0d ]
+ [\x09-\x0d ]
Ket
End
------------------------------------------------------------------
@@ -2671,7 +2667,7 @@ No need char
/[\S]/DZ
------------------------------------------------------------------
Bra
- [\x00-\x08\x0b\x0e-\x1f!-\xff] (neg)
+ [\x00-\x08\x0e-\x1f!-\xff] (neg)
Ket
End
------------------------------------------------------------------
@@ -2782,6 +2778,7 @@ Need char = '0'
End
------------------------------------------------------------------
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -2881,6 +2878,7 @@ No match
End
------------------------------------------------------------------
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -2897,20 +2895,41 @@ No options
First char = 'x'
No need char
-/x{1,3}+/DZ
+/x{1,3}+/BZO
------------------------------------------------------------------
Bra
- Once
x
- x{0,2}
+ x{0,2}+
Ket
+ End
+------------------------------------------------------------------
+
+/x{1,3}+/BZOi
+------------------------------------------------------------------
+ Bra
+ /i x
+ /i x{0,2}+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^x]{1,3}+/BZO
+------------------------------------------------------------------
+ Bra
+ [^x]
+ [^x]{0,2}+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^x]{1,3}+/BZOi
+------------------------------------------------------------------
+ Bra
+ /i [^x]
+ /i [^x]{0,2}+
Ket
End
------------------------------------------------------------------
-Capturing subpattern count = 0
-No options
-First char = 'x'
-No need char
/(x)*+/DZ
------------------------------------------------------------------
@@ -2923,12 +2942,14 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
/^(\w++|\s++)*$/I
Capturing subpattern count = 1
+May match empty string
Options: anchored
No first char
No need char
@@ -3090,7 +3111,7 @@ Need char = 'b'
[bc]+
Ket
CBra 5
- \w*
+ \w*+
Ket
Ket
Ket
@@ -3169,7 +3190,7 @@ Failed: missing terminating ] for character class at offset 10
/[\s]/IDZ
------------------------------------------------------------------
Bra
- [\x09\x0a\x0c\x0d ]
+ [\x09-\x0d ]
Ket
End
------------------------------------------------------------------
@@ -3233,10 +3254,10 @@ No match
End
------------------------------------------------------------------
Capturing subpattern count = 0
+Max lookbehind = 1
No options
First char = '8'
Need char = 'X'
-Max lookbehind = 1
|\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|IDZ
------------------------------------------------------------------
@@ -3247,10 +3268,10 @@ Max lookbehind = 1
End
------------------------------------------------------------------
Capturing subpattern count = 0
+Max lookbehind = 1
No options
First char = '$'
Need char = 'X'
-Max lookbehind = 1
/(.*)\d+\1/I
Capturing subpattern count = 1
@@ -3304,6 +3325,7 @@ Need char = 'b'
/(?=a).*/I
Capturing subpattern count = 0
+May match empty string
No options
First char = 'a'
No need char
@@ -3322,6 +3344,7 @@ Need char = 'z' (caseless)
/(?=a)(?=b)/I
Capturing subpattern count = 0
+May match empty string
No options
First char = 'a'
No need char
@@ -3388,6 +3411,7 @@ Need char = 'a'
/(a)*/I
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
@@ -3616,6 +3640,7 @@ No match
/(?C0)(abc(?C1))*/I
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
@@ -3649,6 +3674,7 @@ No need char
/(\d{3}(?C))*/I
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
@@ -3763,10 +3789,10 @@ Callout 2: last capture = -1
/(?<=(abc)(?C))xyz/I
Capturing subpattern count = 1
+Max lookbehind = 3
No options
First char = 'x'
Need char = 'z'
-Max lookbehind = 3
abcxyz\C+
Callout 0: last capture = 1
0: <unset>
@@ -3785,20 +3811,6 @@ Need char = 'b'
--->abbbbbccc
1 ^ ^
Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
- 1 ^ ^
-Callout data = 1
No match
/a(b+?)(c*?)(?C1)/I
@@ -3895,6 +3907,7 @@ Failed: recursive call could loop indefinitely at offset 16
/^([^()]|\((?1)*\))*$/I
Capturing subpattern count = 1
+May match empty string
Options: anchored
No first char
No need char
@@ -4174,6 +4187,7 @@ Named capturing subpatterns:
one 1
three 3
two 2
+May match empty string
Options: anchored caseless
No first char
No need char
@@ -4273,6 +4287,7 @@ Need char = 'z'
/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a/Is
Capturing subpattern count = 31
+May match empty string
Options: anchored dotall
No first char
No need char
@@ -4280,6 +4295,7 @@ No need char
/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31/Is
Capturing subpattern count = 31
Max back reference = 31
+May match empty string
Options: dotall
No first char
No need char
@@ -4287,6 +4303,7 @@ No need char
/(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32/Is
Capturing subpattern count = 32
Max back reference = 32
+May match empty string
Options: dotall
No first char
No need char
@@ -4363,7 +4380,7 @@ Minimum match() recursion limit = 6
1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaz\M
Minimum match() limit = 32768
-Minimum match() recursion limit = 42
+Minimum match() recursion limit = 29
No match
/(aaa(?C1)bbb|ab)/I
@@ -4438,6 +4455,7 @@ Capturing subpattern count = 2
Named capturing subpatterns:
Tes 1
Test 2
+May match empty string
No options
No first char
No need char
@@ -4456,6 +4474,7 @@ Capturing subpattern count = 2
Named capturing subpatterns:
Tes 2
Test 1
+May match empty string
No options
No first char
No need char
@@ -4533,6 +4552,7 @@ Need char = ']'
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
No options
No first char
No need char
@@ -4553,6 +4573,7 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
No options
No first char
No need char
@@ -4584,6 +4605,7 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
No options
No first char
No need char
@@ -4591,9 +4613,7 @@ No need char
/[ab]{1}+/DZ
------------------------------------------------------------------
Bra
- Once
- [ab]{1,1}
- Ket
+ [ab]{1,1}+
Ket
End
------------------------------------------------------------------
@@ -5305,7 +5325,7 @@ No match
Callout 255 0 21
CBra 1
Callout 255 1 9
- [ab]{1,4}
+ [ab]{1,4}+
Callout 255 10 1
c
Callout 255 11 0
@@ -5318,7 +5338,7 @@ No match
Ket
CBra 1
Callout 255 1 9
- [ab]{1,4}
+ [ab]{1,4}+
Callout 255 10 1
c
Callout 255 11 0
@@ -5331,7 +5351,7 @@ No match
Ket
CBra 1
Callout 255 1 9
- [ab]{1,4}
+ [ab]{1,4}+
Callout 255 10 1
c
Callout 255 11 0
@@ -5344,7 +5364,7 @@ No match
Ket
CBra 1
Callout 255 1 9
- [ab]{1,4}
+ [ab]{1,4}+
Callout 255 10 1
c
Callout 255 11 0
@@ -5358,7 +5378,7 @@ No match
Braminzero
CBra 1
Callout 255 1 9
- [ab]{1,4}
+ [ab]{1,4}+
Callout 255 10 1
c
Callout 255 11 0
@@ -5411,24 +5431,27 @@ Need char = '3'
/\b.*/I
Capturing subpattern count = 0
+Max lookbehind = 1
+May match empty string
No options
No first char
No need char
-Max lookbehind = 1
ab cd\>1
0: cd
/\b.*/Is
Capturing subpattern count = 0
+Max lookbehind = 1
+May match empty string
Options: dotall
No first char
No need char
-Max lookbehind = 1
ab cd\>1
0: cd
/(?!.bcd).*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -6017,6 +6040,7 @@ Matched, but too many substrings
/[^()]*(?:\((?R)\)[^()]*)*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -6029,6 +6053,7 @@ No need char
/[^()]*(?:\((?>(?R))\)[^()]*)*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -6039,6 +6064,7 @@ No need char
/[^()]*(?:\((?R)\))*[^()]*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -6049,6 +6075,7 @@ No need char
/(?:\((?R)\))*[^()]*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -6061,6 +6088,7 @@ No need char
/(?:\((?R)\))|[^()]*/I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -6110,6 +6138,17 @@ no parentheses with name "Z"
2: a1
copy substring Z failed -7
C a1 (2) A
+
+/(?|(?<a>)(?<b>)(?<a>)|(?<a>)(?<b>)(?<a>))/IJ
+Capturing subpattern count = 3
+Named capturing subpatterns:
+ a 1
+ a 3
+ b 2
+May match empty string
+Options: dupnames
+No first char
+No need char
/^(?P<A>a)(?P<A>b)/IJ
Capturing subpattern count = 2
@@ -6320,7 +6359,7 @@ Need char = 'X'
1: X
/(?:(?(2y)a|b)(X))+/I
-Failed: reference to non-existent subpattern at offset 9
+Failed: malformed number or name after (?( at offset 7
/(?:(?(ZA)a|b)(?P<ZZ>X))+/I
Failed: reference to non-existent subpattern at offset 9
@@ -6392,9 +6431,9 @@ No options
No first char
Need char = ','
Subject length lower bound = 1
-Starting byte set: \x09 \x0a \x0c \x0d \x20 ,
+Starting byte set: \x09 \x0a \x0b \x0c \x0d \x20 ,
\x0b,\x0b
- 0: ,
+ 0: \x0b,\x0b
\x0c,\x0d
0: \x0c,\x0d
@@ -6503,7 +6542,7 @@ No match
No match
/^abc/Im<bad>
-Unknown newline type at: <bad>
+Unknown modifier at: <bad>
/abc/I
@@ -6512,12 +6551,13 @@ No options
First char = 'a'
Need char = 'c'
xyz\rabc\<bad>
-Unknown newline type at: <bad>
+Unknown escape sequence at: <bad>
abc
0: abc
/.*/I<lf>
Capturing subpattern count = 0
+May match empty string
Options:
Forced newline sequence: LF
First char at start or follows newline
@@ -6559,6 +6599,7 @@ Need char = 'f'
+((?:\s|//.*\\n|/[*](?:\\n|.)*?[*]/)*)+I
Capturing subpattern count = 1
+May match empty string
No options
No first char
No need char
@@ -7482,7 +7523,7 @@ Matched, but too many substrings
/a*[^a]/BZ
------------------------------------------------------------------
Bra
- a*
+ a*+
[^a]
Ket
End
@@ -7624,7 +7665,7 @@ No match
------------------------------------------------------------------
Bra
^
- [a-z]+
+ [a-z]++
Ket
End
------------------------------------------------------------------
@@ -7665,7 +7706,7 @@ No match
^
CBra 1
Cond
- 2 Cond nref
+ 2 Cond ref
y
Ket
[()]
@@ -7725,6 +7766,7 @@ Named capturing subpatterns:
one 1
three 3
two 2
+May match empty string
Options: anchored caseless
No first char
No need char
@@ -7824,15 +7866,9 @@ Failed: reference to non-existent subpattern at offset 7
1: abcabc1Xabc2XabcX
2: abcabc1Xabc2XabcX
-/(?<A> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x
+/(?<A> (?'B' abc (?(R) (?(R&C)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x
Failed: reference to non-existent subpattern at offset 29
-/(?<1> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) /x
- abcabc1Xabc2XabcXabcabc
- 0: abcabc1Xabc2XabcX
- 1: abcabc1Xabc2XabcX
- 2: abcabc1Xabc2XabcX
-
/^(?(DEFINE) abc | xyz ) /x
Failed: DEFINE group contains more than one branch at offset 22
@@ -8056,7 +8092,7 @@ Failed: a numbered reference must not be zero at offset 8
/^(a)\g{3/
Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 8
-/^(a)\g{4a}/
+/^(a)\g{aa}/
Failed: reference to non-existent subpattern at offset 9
/^a.b/<lf>
@@ -8561,7 +8597,7 @@ No match
\d
\v++
\w
- \v+
+ \v++
\S
\v++
\V
@@ -8659,27 +8695,18 @@ No match
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
- +4 ^ ^ c+
- +2 ^ ^ b?
- +4 ^ ^ c+
- +2 ^^ b?
- +4 ^^ c+
+0 ^ a+
+2 ^ ^ b?
+4 ^ ^ c+
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
- +4 ^ ^ c+
- +2 ^^ b?
- +4 ^^ c+
+0 ^ a+
+2 ^^ b?
+4 ^ ^ c+
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
+6 ^ ^ (*FAIL)
- +4 ^^ c+
No match
/a+b?(*PRUNE)c+(*FAIL)/C
@@ -8803,7 +8830,7 @@ No match
1: \x0a
/a(*CR)b/
-Failed: (*VERB) not recognized at offset 5
+Failed: (*VERB) not recognized or malformed at offset 5
/(*CR)a.b/
a\nb
@@ -9248,8 +9275,28 @@ No match
ab
No match
-/a(?!)+b/
-Failed: nothing to repeat at offset 5
+/a(?!)b/BZ
+------------------------------------------------------------------
+ Bra
+ a
+ *FAIL
+ b
+ Ket
+ End
+------------------------------------------------------------------
+
+/(?!)?a/BZ
+------------------------------------------------------------------
+ Bra
+ Brazero
+ Assert not
+ Ket
+ a
+ Ket
+ End
+------------------------------------------------------------------
+ ab
+ 0: a
/a(*FAIL)+b/
Failed: nothing to repeat at offset 8
@@ -9264,6 +9311,7 @@ Starting byte set: x y z
/(?(?=.*b)b|^)/CI
Capturing subpattern count = 0
+May match empty string
Options:
No first char
No need char
@@ -9276,6 +9324,7 @@ No need char
+7 ^ ^ b
+7 ^^ b
+7 ^ b
++11 ^ ^
+12 ^ )
+13 ^
0:
@@ -9367,7 +9416,7 @@ No match
No match
/(*NO_START_OPT)xyz/C
- abcxyz
+ abcxyz
--->abcxyz
+15 ^ x
+15 ^ x
@@ -9377,6 +9426,15 @@ No match
+17 ^ ^ z
+18 ^ ^
0: xyz
+
+/(*NO_AUTO_POSSESS)a+b/BZ
+------------------------------------------------------------------
+ Bra
+ a+
+ b
+ Ket
+ End
+------------------------------------------------------------------
/xyz/CY
abcxyz
@@ -9406,12 +9464,14 @@ No match
+3 ^ ^ (?(?=[a])[^"])
+5 ^ ^ (?=[a])
+8 ^ ^ [a]
++17 ^ ^ |
+21 ^ ^ "
+18 ^ ^ b
+19 ^ ^ )
+3 ^ ^ (?(?=[a])[^"])
+5 ^ ^ (?=[a])
+8 ^ ^ [a]
++17 ^ ^ |
+21 ^ ^ "
+22 ^ ^ $
+23 ^ ^
@@ -9719,17 +9779,17 @@ Partial match: abc12
xyzabc123pqr
0: 123
xyzabc12\P
-Partial match: abc12
+Partial match at offset 6: abc12
xyzabc12\P\P
-Partial match: abc12
+Partial match at offset 6: abc12
/\babc\b/
+++abc+++
0: abc
+++ab\P
-Partial match: +ab
+Partial match at offset 3: +ab
+++ab\P\P
-Partial match: +ab
+Partial match at offset 3: +ab
/(?&word)(?&element)(?(DEFINE)(?<element><[^m][^>]>[^<])(?<word>\w*+))/BZ
------------------------------------------------------------------
@@ -10172,7 +10232,6 @@ No set of starting bytes
Capturing subpattern count = 1
Named capturing subpatterns:
a 1
- a 1
No options
No first char
No need char
@@ -10245,7 +10304,7 @@ No match
Ket
Ket
Cond
- 4 Cond nref
+ Cond ref <D>2
X
Alt
Y
@@ -10291,7 +10350,7 @@ No match
CBra 4
d
Cond
- Cond nrecurse 1
+ Cond recurse <A>2
$
Alt
Recurse
@@ -10353,7 +10412,7 @@ Partial match: abca
xxxxabcde\P\P
Partial match: abcde
-/-- This is not in the Perl >= 5.10 test because Perl seems currently to be
+/-- This is not in the Perl-compatible test because Perl seems currently to be
broken and not behaving as specified in that it *does* bumpalong after
hitting (*COMMIT). --/
@@ -10549,34 +10608,14 @@ No match
End
------------------------------------------------------------------
-/ -- The first four of these are not in the Perl >= 5.10 test because Perl
- documents that the use of \K in assertions is "not well defined". The
- last is here because Perl gives the match as "b" rather than "ab". I
+/ -- This one is here because Perl gives the match as "b" rather than "ab". I
believe this to be a Perl bug. --/
-/(?=a\Kb)ab/
- ab
- 0: b
-
-/(?!a\Kb)ac/
- ac
- 0: ac
-
-/^abc(?<=b\Kc)d/
- abcd
- 0: cd
-
-/^abc(?<!b\Kq)d/
- abcd
- 0: abcd
-
/(?>a\Kb)z|(ab)/
ab
0: ab
1: ab
-/----------------------/
-
/(?P<L1>(?P<L2>0|)|(?P>L2)(?P>L1))/
Failed: recursive call could loop indefinitely at offset 31
@@ -10596,7 +10635,7 @@ Failed: an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) at offse
ACABX
No match
-/--- These should be different, but in Perl 5.11 are not, which I think
+/--- These should be different, but in Perl they are not, which I think
is a bug in Perl. ---/
/A(*THEN)B|A(*THEN)C/K
@@ -10607,13 +10646,6 @@ No match
AC
No match
-/--- This should fail; the SKIP advances by one, but when we get to AC, the
- PRUNE kills it. Perl behaves differently. ---/
-
-/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/xK
- AAAC
-No match, mark = A
-
/--- Mark names can be duplicated. Perl doesn't give a mark for this one,
though PCRE does. ---/
@@ -10647,7 +10679,7 @@ No match
abcccd
No match
-/--- Perl 5.11 gets some of these wrong ---/
+/--- Perl gets some of these wrong ---/
/(?>.(*ACCEPT))*?5/
abcde
@@ -10826,21 +10858,9 @@ No match
X\x0d\x0a
No match
-/-- Perl treats this one differently, not failing the second string. I believe
- that is a bug in Perl. --/
-
-/^((abc|abcx)(*THEN)y|abcd)/
- abcd
- 0: abcd
- 1: abcd
- *** Failers
-No match
- abcxy
-No match
-
/(?<=abc)def/
abc\P\P
-Partial match: abc
+Partial match at offset 3: abc
/abc$/
abc
@@ -11087,12 +11107,14 @@ No need char
/(^ab|^)+/I
Capturing subpattern count = 1
+May match empty string
Options: anchored
No first char
No need char
/(^ab|^)++/I
Capturing subpattern count = 1
+May match empty string
Options: anchored
No first char
No need char
@@ -11111,12 +11133,14 @@ No need char
/(?:^ab|^)+/I
Capturing subpattern count = 0
+May match empty string
Options: anchored
No first char
No need char
/(?:^ab|^)++/I
Capturing subpattern count = 0
+May match empty string
Options: anchored
No first char
No need char
@@ -11135,12 +11159,14 @@ Need char = 'b'
/(.*ab|.*)+/I
Capturing subpattern count = 1
+May match empty string
No options
First char at start or follows newline
No need char
/(.*ab|.*)++/I
Capturing subpattern count = 1
+May match empty string
No options
First char at start or follows newline
No need char
@@ -11159,12 +11185,14 @@ Need char = 'b'
/(?:.*ab|.*)+/I
Capturing subpattern count = 0
+May match empty string
No options
First char at start or follows newline
No need char
/(?:.*ab|.*)++/I
Capturing subpattern count = 0
+May match empty string
No options
First char at start or follows newline
No need char
@@ -11319,7 +11347,6 @@ No match
/(a)b|ac/++SS
ac\O3
-Matched, but too many substrings
0: ac
0+
@@ -11571,7 +11598,7 @@ Matched, but too many substrings
Assert not
a
Ket
- \w+
+ \w++
Ket
End
------------------------------------------------------------------
@@ -11679,28 +11706,30 @@ No match
/\btype\b\W*?\btext\b\W*?\bjavascript\b/IS
Capturing subpattern count = 0
+Max lookbehind = 1
No options
First char = 't'
Need char = 't'
-Max lookbehind = 1
Subject length lower bound = 18
No set of starting bytes
/\btype\b\W*?\btext\b\W*?\bjavascript\b|\burl\b\W*?\bshell:|<input\b.*?\btype\b\W*?\bimage\b|\bonkeyup\b\W*?\=/IS
Capturing subpattern count = 0
+Max lookbehind = 1
No options
No first char
No need char
-Max lookbehind = 1
Subject length lower bound = 8
Starting byte set: < o t u
-/a(*SKIP)c|b(*ACCEPT)|/+SI
+/a(*SKIP)c|b(*ACCEPT)|/+S!I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
-Study returned NULL
+Subject length lower bound = -1
+No set of starting bytes
a
0:
0+
@@ -11761,75 +11790,16 @@ Minimum match() limit = 86
Minimum match() recursion limit = 45
0: abbbbbbbbbbbbbbbbbbbbba
-/-- These tests are in agreement with development Perl 5.015, which has fixed
- some things, but they don't all work with 5.012, so they aren't in the
- Perl-compatible tests. Those after the first come from Perl's own test
- files. --/
-
-/^((yes|no)(*THEN)(*F))?/
- yes
-No match
-
-/(A (.*) C? (*THEN) | A D) (*FAIL)/x
-AbcdCBefgBhiBqz
-No match
-
-/(A (.*) C? (*THEN) | A D) z/x
-AbcdCBefgBhiBqz
-No match
-
-/(A (.*) C? (*THEN) | A D) \s* (*FAIL)/x
-AbcdCBefgBhiBqz
-No match
-
-/(A (.*) C? (*THEN) | A D) \s* z/x
-AbcdCBefgBhiBqz
-No match
-
-/(A (.*) (?:C|) (*THEN) | A D) (*FAIL)/x
-AbcdCBefgBhiBqz
-No match
-
-/(A (.*) (?:C|) (*THEN) | A D) z/x
-AbcdCBefgBhiBqz
-No match
-
-/(A (.*) C{0,6} (*THEN) | A D) (*FAIL)/x
-AbcdCBefgBhiBqz
-No match
-
-/(A (.*) C{0,6} (*THEN) | A D) z/x
-AbcdCBefgBhiBqz
-No match
-
-/(A (.*) (CE){0,6} (*THEN) | A D) (*FAIL)/x
-AbcdCEBefgBhiBqz
-No match
-
-/(A (.*) (CE){0,6} (*THEN) | A D) z/x
-AbcdCEBefgBhiBqz
-No match
-
-/(A (.*) (CE*){0,6} (*THEN) | A D) (*FAIL)/x
-AbcdCBefgBhiBqz
-No match
-
-/(A (.*) (CE*){0,6} (*THEN) | A D) z/x
-AbcdCBefgBhiBqz
-No match
-
-/-----------------------------------------------/
-
/^(?>a+)(?>(z+))\w/BZ
------------------------------------------------------------------
Bra
^
Once_NC
- a+
+ a++
Ket
Once
CBra 1
- z+
+ z++
Ket
Ket
\w
@@ -11888,14 +11858,14 @@ No match
/^(?>a+)(?>b+)(?>c+)(?>d+)(?>e+)/
\Maabbccddee
-Minimum match() limit = 12
-Minimum match() recursion limit = 3
+Minimum match() limit = 7
+Minimum match() recursion limit = 2
0: aabbccddee
/^(?>(a+))(?>(b+))(?>(c+))(?>(d+))(?>(e+))/
\Maabbccddee
-Minimum match() limit = 22
-Minimum match() recursion limit = 21
+Minimum match() limit = 17
+Minimum match() recursion limit = 16
0: aabbccddee
1: aa
2: bb
@@ -11905,8 +11875,8 @@ Minimum match() recursion limit = 21
/^(?>(a+))(?>b+)(?>(c+))(?>d+)(?>(e+))/
\Maabbccddee
-Minimum match() limit = 18
-Minimum match() recursion limit = 13
+Minimum match() limit = 13
+Minimum match() recursion limit = 10
0: aabbccddee
1: aa
2: cc
@@ -11997,7 +11967,10 @@ No match
Failed: \N is not supported in a class at offset 3
/a[B-\Nc]/
-Failed: \N is not supported in a class at offset 5
+Failed: invalid range in character class at offset 5
+
+/a[B\Nc]/
+Failed: \N is not supported in a class at offset 4
/(a)(?2){0,1999}?(b)/
@@ -12336,47 +12309,27 @@ Partial match: \x0d\x0d
\r\r\r\P\P
0: \x0d\x0d
-/-- These two are here because Perl does not match: it seems to allow the
-COMMIT to escape from the assertion. --/
-
-/(?=a(*COMMIT)b|ac)ac|ac/
- ac
- 0: ac
-
-/(?=a(*COMMIT)b|(ac)) ac | (a)c/x
- ac
- 0: ac
- 1: <unset>
- 2: a
-
"AB(C(D))(E(F))?(?(?=\2)(?=\4))"
ABCDGHI\O03
Matched, but too many substrings
0: ABCD
-/-- This one is here because Perl does not confine the *COMMIT to the
-assertion, and therefore fails the entire subroutine call. --/
-
-/((?=a(*COMMIT)b)ab|ac){0}(?:(?1)|a(c))/
- ac
- 0: ac
-
/-- These are all run as real matches in test 1; here we are just checking the
settings of the anchored and startline bits. --/
/(?>.*?a)(?<=ba)/I
Capturing subpattern count = 0
+Max lookbehind = 2
No options
No first char
Need char = 'a'
-Max lookbehind = 2
/(?:.*?a)(?<=ba)/I
Capturing subpattern count = 0
+Max lookbehind = 2
No options
First char at start or follows newline
Need char = 'a'
-Max lookbehind = 2
/.*?a(*PRUNE)b/I
Capturing subpattern count = 0
@@ -12422,17 +12375,19 @@ No need char
/(?>.*?)(?<=(abcd)|(wxyz))/I
Capturing subpattern count = 2
+Max lookbehind = 4
+May match empty string
No options
No first char
No need char
-Max lookbehind = 4
/(?>.*)(?<=(abcd)|(wxyz))/I
Capturing subpattern count = 2
+Max lookbehind = 4
+May match empty string
No options
No first char
No need char
-Max lookbehind = 4
"(?>.*)foo"I
Capturing subpattern count = 0
@@ -12468,6 +12423,7 @@ Need char = 'c'
/.?/S-I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
@@ -12475,10 +12431,1698 @@ Study returned NULL
/.?/S!I
Capturing subpattern count = 0
+May match empty string
No options
No first char
No need char
Subject length lower bound = -1
No set of starting bytes
+/(?:(a)+(?C1)bb|aa(?C2)b)/
+ aab\C+
+Callout 1: last capture = 1
+ 0: <unset>
+ 1: a
+--->aab
+ ^ ^ b
+Callout 1: last capture = 1
+ 0: <unset>
+ 1: a
+--->aab
+ ^^ b
+Callout 2: last capture = -1
+ 0: <unset>
+--->aab
+ ^ ^ b
+ 0: aab
+
+/(?:(a)++(?C1)bb|aa(?C2)b)/
+ aab\C+
+Callout 1: last capture = 1
+ 0: <unset>
+ 1: a
+--->aab
+ ^ ^ b
+Callout 2: last capture = -1
+ 0: <unset>
+--->aab
+ ^ ^ b
+ 0: aab
+
+/(?:(?>(a))(?C1)bb|aa(?C2)b)/
+ aab\C+
+Callout 1: last capture = 1
+ 0: <unset>
+ 1: a
+--->aab
+ ^^ b
+Callout 2: last capture = -1
+ 0: <unset>
+--->aab
+ ^ ^ b
+ 0: aab
+
+/(?:(?1)(?C1)x|ab(?C2))((a)){0}/
+ aab\C+
+Callout 1: last capture = -1
+ 0: <unset>
+--->aab
+ ^^ x
+Callout 1: last capture = -1
+ 0: <unset>
+--->aab
+ ^^ x
+Callout 2: last capture = -1
+ 0: <unset>
+--->aab
+ ^ ^ )
+ 0: ab
+
+/(?1)(?C1)((a)(?C2)){0}/
+ aab\C+
+Callout 2: last capture = 2
+ 0: <unset>
+ 1: <unset>
+ 2: a
+--->aab
+ ^^ )
+Callout 1: last capture = -1
+ 0: <unset>
+--->aab
+ ^^ ((a)(?C2)){0}
+ 0: a
+
+/(?:(a)+(?C1)bb|aa(?C2)b)++/
+ aab\C+
+Callout 1: last capture = 1
+ 0: <unset>
+ 1: a
+--->aab
+ ^ ^ b
+Callout 1: last capture = 1
+ 0: <unset>
+ 1: a
+--->aab
+ ^^ b
+Callout 2: last capture = -1
+ 0: <unset>
+--->aab
+ ^ ^ b
+ 0: aab
+ aab\C+\O2
+Callout 1: last capture = 1
+ 0: <unset>
+--->aab
+ ^ ^ b
+Callout 1: last capture = 1
+ 0: <unset>
+--->aab
+ ^^ b
+Callout 2: last capture = -1
+ 0: <unset>
+--->aab
+ ^ ^ b
+ 0: aab
+
+/(ab)x|ab/
+ ab\O3
+ 0: ab
+ ab\O2
+ 0: ab
+
+/(ab)/
+ ab\O3
+Matched, but too many substrings
+ 0: ab
+ ab\O2
+Matched, but too many substrings
+ 0: ab
+
+/(?<=123)(*MARK:xx)abc/K
+ xxxx123a\P\P
+Partial match at offset 7, mark=xx: 123a
+ xxxx123a\P
+Partial match at offset 7, mark=xx: 123a
+
+/123\Kabc/
+ xxxx123a\P\P
+Partial match: 123a
+ xxxx123a\P
+Partial match: 123a
+
+/^(?(?=a)aa|bb)/C
+ bb
+--->bb
+ +0 ^ ^
+ +1 ^ (?(?=a)aa|bb)
+ +3 ^ (?=a)
+ +6 ^ a
++11 ^ b
++12 ^^ b
++13 ^ ^ )
++14 ^ ^
+ 0: bb
+
+/(?C1)^(?C2)(?(?C99)(?=(?C3)a(?C4))(?C5)a(?C6)a(?C7)|(?C8)b(?C9)b(?C10))(?C11)/
+ bb
+--->bb
+ 1 ^ ^
+ 2 ^ (?(?C99)(?=(?C3)a(?C4))(?C5)a(?C6)a(?C7)|(?C8)b(?C9)b(?C10))
+ 99 ^ (?=(?C3)a(?C4))
+ 3 ^ a
+ 8 ^ b
+ 9 ^^ b
+ 10 ^ ^ )
+ 11 ^ ^
+ 0: bb
+
+/-- Perl seems to have a bug with this one --/
+
+/aaaaa(*COMMIT)(*PRUNE)b|a+c/
+ aaaaaac
+ 0: aaaac
+
+/-- Here are some that Perl treats differently because of the way it handles
+backtracking verbs. --/
+
+ /(?!a(*COMMIT)b)ac|ad/
+ ac
+ 0: ac
+ ad
+ 0: ad
+
+/^(?!a(*THEN)b|ac)../
+ ac
+No match
+ ad
+ 0: ad
+
+/^(?=a(*THEN)b|ac)/
+ ac
+ 0:
+
+/\A.*?(?:a|b(*THEN)c)/
+ ba
+ 0: ba
+
+/\A.*?(?:a|b(*THEN)c)++/
+ ba
+ 0: ba
+
+/\A.*?(?:a|b(*THEN)c|d)/
+ ba
+ 0: ba
+
+/(?:(a(*MARK:X)a+(*SKIP:X)b)){0}(?:(?1)|aac)/
+ aac
+ 0: aac
+
+/\A.*?(a|b(*THEN)c)/
+ ba
+ 0: ba
+ 1: a
+
+/^(A(*THEN)B|A(*THEN)D)/
+ AD
+ 0: AD
+ 1: AD
+
+/(?!b(*THEN)a)bn|bnn/
+ bnn
+ 0: bn
+
+/(?(?=b(*SKIP)a)bn|bnn)/
+ bnn
+No match
+
+/(?=b(*THEN)a|)bn|bnn/
+ bnn
+ 0: bn
+
+/-------------------------/
+
+/(*LIMIT_MATCH=12bc)abc/
+Failed: (*VERB) not recognized or malformed at offset 7
+
+/(*LIMIT_MATCH=4294967290)abc/
+Failed: (*VERB) not recognized or malformed at offset 7
+
+/(*LIMIT_RECURSION=4294967280)abc/I
+Capturing subpattern count = 0
+Recursion limit = 4294967280
+No options
+First char = 'a'
+Need char = 'c'
+
+/(a+)*zz/
+ aaaaaaaaaaaaaz
+No match
+ aaaaaaaaaaaaaz\q3000
+Error -8 (match limit exceeded)
+
+/(a+)*zz/S-
+ aaaaaaaaaaaaaz\Q10
+Error -21 (recursion limit exceeded)
+
+/(*LIMIT_MATCH=3000)(a+)*zz/I
+Capturing subpattern count = 1
+Match limit = 3000
+No options
+No first char
+Need char = 'z'
+ aaaaaaaaaaaaaz
+Error -8 (match limit exceeded)
+ aaaaaaaaaaaaaz\q60000
+Error -8 (match limit exceeded)
+
+/(*LIMIT_MATCH=60000)(*LIMIT_MATCH=3000)(a+)*zz/I
+Capturing subpattern count = 1
+Match limit = 3000
+No options
+No first char
+Need char = 'z'
+ aaaaaaaaaaaaaz
+Error -8 (match limit exceeded)
+
+/(*LIMIT_MATCH=60000)(a+)*zz/I
+Capturing subpattern count = 1
+Match limit = 60000
+No options
+No first char
+Need char = 'z'
+ aaaaaaaaaaaaaz
+No match
+ aaaaaaaaaaaaaz\q3000
+Error -8 (match limit exceeded)
+
+/(*LIMIT_RECURSION=10)(a+)*zz/IS-
+Capturing subpattern count = 1
+Recursion limit = 10
+No options
+No first char
+Need char = 'z'
+Subject length lower bound = 2
+Starting byte set: a z
+ aaaaaaaaaaaaaz
+Error -21 (recursion limit exceeded)
+ aaaaaaaaaaaaaz\Q1000
+Error -21 (recursion limit exceeded)
+
+/(*LIMIT_RECURSION=10)(*LIMIT_RECURSION=1000)(a+)*zz/IS-
+Capturing subpattern count = 1
+Recursion limit = 10
+No options
+No first char
+Need char = 'z'
+Subject length lower bound = 2
+Starting byte set: a z
+ aaaaaaaaaaaaaz
+Error -21 (recursion limit exceeded)
+
+/(*LIMIT_RECURSION=1000)(a+)*zz/IS-
+Capturing subpattern count = 1
+Recursion limit = 1000
+No options
+No first char
+Need char = 'z'
+Subject length lower bound = 2
+Starting byte set: a z
+ aaaaaaaaaaaaaz
+No match
+ aaaaaaaaaaaaaz\Q10
+Error -21 (recursion limit exceeded)
+
+/-- This test causes a segfault with Perl 5.18.0 --/
+
+/^(?=(a)){0}b(?1)/
+ backgammon
+ 0: ba
+
+/(?|(?<n>f)|(?<n>b))/JI
+Capturing subpattern count = 1
+Named capturing subpatterns:
+ n 1
+Options: dupnames
+No first char
+No need char
+
+/(?<a>abc)(?<a>z)\k<a>()/JDZS
+------------------------------------------------------------------
+ Bra
+ CBra 1
+ abc
+ Ket
+ CBra 2
+ z
+ Ket
+ \k<a>2
+ CBra 3
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 3
+Max back reference = 2
+Named capturing subpatterns:
+ a 1
+ a 2
+Options: dupnames
+First char = 'a'
+Need char = 'z'
+Subject length lower bound = 5
+No set of starting bytes
+
+/a*[bcd]/BZ
+------------------------------------------------------------------
+ Bra
+ a*+
+ [b-d]
+ Ket
+ End
+------------------------------------------------------------------
+
+/[bcd]*a/BZ
+------------------------------------------------------------------
+ Bra
+ [b-d]*+
+ a
+ Ket
+ End
+------------------------------------------------------------------
+
+/-- A complete set of tests for auto-possessification of character types --/
+
+/\D+\D \D+\d \D+\S \D+\s \D+\W \D+\w \D+. \D+\C \D+\R \D+\H \D+\h \D+\V \D+\v \D+\Z \D+\z \D+$/BZx
+------------------------------------------------------------------
+ Bra
+ \D+
+ \D
+ \D++
+ \d
+ \D+
+ \S
+ \D+
+ \s
+ \D+
+ \W
+ \D+
+ \w
+ \D+
+ Any
+ \D+
+ AllAny
+ \D+
+ \R
+ \D+
+ \H
+ \D+
+ \h
+ \D+
+ \V
+ \D+
+ \v
+ \D+
+ \Z
+ \D++
+ \z
+ \D+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\d+\D \d+\d \d+\S \d+\s \d+\W \d+\w \d+. \d+\C \d+\R \d+\H \d+\h \d+\V \d+\v \d+\Z \d+\z \d+$/BZx
+------------------------------------------------------------------
+ Bra
+ \d++
+ \D
+ \d+
+ \d
+ \d+
+ \S
+ \d++
+ \s
+ \d++
+ \W
+ \d+
+ \w
+ \d+
+ Any
+ \d+
+ AllAny
+ \d++
+ \R
+ \d+
+ \H
+ \d++
+ \h
+ \d+
+ \V
+ \d++
+ \v
+ \d++
+ \Z
+ \d++
+ \z
+ \d++
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\S+\D \S+\d \S+\S \S+\s \S+\W \S+\w \S+. \S+\C \S+\R \S+\H \S+\h \S+\V \S+\v \S+\Z \S+\z \S+$/BZx
+------------------------------------------------------------------
+ Bra
+ \S+
+ \D
+ \S+
+ \d
+ \S+
+ \S
+ \S++
+ \s
+ \S+
+ \W
+ \S+
+ \w
+ \S+
+ Any
+ \S+
+ AllAny
+ \S++
+ \R
+ \S+
+ \H
+ \S++
+ \h
+ \S+
+ \V
+ \S++
+ \v
+ \S++
+ \Z
+ \S++
+ \z
+ \S++
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\s+\D \s+\d \s+\S \s+\s \s+\W \s+\w \s+. \s+\C \s+\R \s+\H \s+\h \s+\V \s+\v \s+\Z \s+\z \s+$/BZx
+------------------------------------------------------------------
+ Bra
+ \s+
+ \D
+ \s++
+ \d
+ \s++
+ \S
+ \s+
+ \s
+ \s+
+ \W
+ \s++
+ \w
+ \s+
+ Any
+ \s+
+ AllAny
+ \s+
+ \R
+ \s+
+ \H
+ \s+
+ \h
+ \s+
+ \V
+ \s+
+ \v
+ \s+
+ \Z
+ \s++
+ \z
+ \s+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\W+\D \W+\d \W+\S \W+\s \W+\W \W+\w \W+. \W+\C \W+\R \W+\H \W+\h \W+\V \W+\v \W+\Z \W+\z \W+$/BZx
+------------------------------------------------------------------
+ Bra
+ \W+
+ \D
+ \W++
+ \d
+ \W+
+ \S
+ \W+
+ \s
+ \W+
+ \W
+ \W++
+ \w
+ \W+
+ Any
+ \W+
+ AllAny
+ \W+
+ \R
+ \W+
+ \H
+ \W+
+ \h
+ \W+
+ \V
+ \W+
+ \v
+ \W+
+ \Z
+ \W++
+ \z
+ \W+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\w+\D \w+\d \w+\S \w+\s \w+\W \w+\w \w+. \w+\C \w+\R \w+\H \w+\h \w+\V \w+\v \w+\Z \w+\z \w+$/BZx
+------------------------------------------------------------------
+ Bra
+ \w+
+ \D
+ \w+
+ \d
+ \w+
+ \S
+ \w++
+ \s
+ \w++
+ \W
+ \w+
+ \w
+ \w+
+ Any
+ \w+
+ AllAny
+ \w++
+ \R
+ \w+
+ \H
+ \w++
+ \h
+ \w+
+ \V
+ \w++
+ \v
+ \w++
+ \Z
+ \w++
+ \z
+ \w++
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\C+\D \C+\d \C+\S \C+\s \C+\W \C+\w \C+. \C+\C \C+\R \C+\H \C+\h \C+\V \C+\v \C+\Z \C+\z \C+$/BZx
+------------------------------------------------------------------
+ Bra
+ AllAny+
+ \D
+ AllAny+
+ \d
+ AllAny+
+ \S
+ AllAny+
+ \s
+ AllAny+
+ \W
+ AllAny+
+ \w
+ AllAny+
+ Any
+ AllAny+
+ AllAny
+ AllAny+
+ \R
+ AllAny+
+ \H
+ AllAny+
+ \h
+ AllAny+
+ \V
+ AllAny+
+ \v
+ AllAny+
+ \Z
+ AllAny++
+ \z
+ AllAny+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\R+\D \R+\d \R+\S \R+\s \R+\W \R+\w \R+. \R+\C \R+\R \R+\H \R+\h \R+\V \R+\v \R+\Z \R+\z \R+$/BZx
+------------------------------------------------------------------
+ Bra
+ \R+
+ \D
+ \R++
+ \d
+ \R+
+ \S
+ \R++
+ \s
+ \R+
+ \W
+ \R++
+ \w
+ \R++
+ Any
+ \R+
+ AllAny
+ \R+
+ \R
+ \R+
+ \H
+ \R++
+ \h
+ \R+
+ \V
+ \R+
+ \v
+ \R+
+ \Z
+ \R++
+ \z
+ \R+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\H+\D \H+\d \H+\S \H+\s \H+\W \H+\w \H+. \H+\C \H+\R \H+\H \H+\h \H+\V \H+\v \H+\Z \H+\z \H+$/BZx
+------------------------------------------------------------------
+ Bra
+ \H+
+ \D
+ \H+
+ \d
+ \H+
+ \S
+ \H+
+ \s
+ \H+
+ \W
+ \H+
+ \w
+ \H+
+ Any
+ \H+
+ AllAny
+ \H+
+ \R
+ \H+
+ \H
+ \H++
+ \h
+ \H+
+ \V
+ \H+
+ \v
+ \H+
+ \Z
+ \H++
+ \z
+ \H+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\h+\D \h+\d \h+\S \h+\s \h+\W \h+\w \h+. \h+\C \h+\R \h+\H \h+\h \h+\V \h+\v \h+\Z \h+\z \h+$/BZx
+------------------------------------------------------------------
+ Bra
+ \h+
+ \D
+ \h++
+ \d
+ \h++
+ \S
+ \h+
+ \s
+ \h+
+ \W
+ \h++
+ \w
+ \h+
+ Any
+ \h+
+ AllAny
+ \h++
+ \R
+ \h++
+ \H
+ \h+
+ \h
+ \h+
+ \V
+ \h++
+ \v
+ \h+
+ \Z
+ \h++
+ \z
+ \h+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\V+\D \V+\d \V+\S \V+\s \V+\W \V+\w \V+. \V+\C \V+\R \V+\H \V+\h \V+\V \V+\v \V+\Z \V+\z \V+$/BZx
+------------------------------------------------------------------
+ Bra
+ \V+
+ \D
+ \V+
+ \d
+ \V+
+ \S
+ \V+
+ \s
+ \V+
+ \W
+ \V+
+ \w
+ \V+
+ Any
+ \V+
+ AllAny
+ \V++
+ \R
+ \V+
+ \H
+ \V+
+ \h
+ \V+
+ \V
+ \V++
+ \v
+ \V+
+ \Z
+ \V++
+ \z
+ \V+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\v+\D \v+\d \v+\S \v+\s \v+\W \v+\w \v+. \v+\C \v+\R \v+\H \v+\h \v+\V \v+\v \v+\Z \v+\z \v+$/BZx
+------------------------------------------------------------------
+ Bra
+ \v+
+ \D
+ \v++
+ \d
+ \v++
+ \S
+ \v+
+ \s
+ \v+
+ \W
+ \v++
+ \w
+ \v+
+ Any
+ \v+
+ AllAny
+ \v+
+ \R
+ \v+
+ \H
+ \v++
+ \h
+ \v++
+ \V
+ \v+
+ \v
+ \v+
+ \Z
+ \v++
+ \z
+ \v+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/ a+\D a+\d a+\S a+\s a+\W a+\w a+. a+\C a+\R a+\H a+\h a+\V a+\v a+\Z a+\z a+$/BZx
+------------------------------------------------------------------
+ Bra
+ a+
+ \D
+ a++
+ \d
+ a+
+ \S
+ a++
+ \s
+ a++
+ \W
+ a+
+ \w
+ a+
+ Any
+ a+
+ AllAny
+ a++
+ \R
+ a+
+ \H
+ a++
+ \h
+ a+
+ \V
+ a++
+ \v
+ a++
+ \Z
+ a++
+ \z
+ a++
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\n+\D \n+\d \n+\S \n+\s \n+\W \n+\w \n+. \n+\C \n+\R \n+\H \n+\h \n+\V \n+\v \n+\Z \n+\z \n+$/BZx
+------------------------------------------------------------------
+ Bra
+ \x0a+
+ \D
+ \x0a++
+ \d
+ \x0a++
+ \S
+ \x0a+
+ \s
+ \x0a+
+ \W
+ \x0a++
+ \w
+ \x0a+
+ Any
+ \x0a+
+ AllAny
+ \x0a+
+ \R
+ \x0a+
+ \H
+ \x0a++
+ \h
+ \x0a++
+ \V
+ \x0a+
+ \v
+ \x0a+
+ \Z
+ \x0a++
+ \z
+ \x0a+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/ .+\D .+\d .+\S .+\s .+\W .+\w .+. .+\C .+\R .+\H .+\h .+\V .+\v .+\Z .+\z .+$/BZx
+------------------------------------------------------------------
+ Bra
+ Any+
+ \D
+ Any+
+ \d
+ Any+
+ \S
+ Any+
+ \s
+ Any+
+ \W
+ Any+
+ \w
+ Any+
+ Any
+ Any+
+ AllAny
+ Any++
+ \R
+ Any+
+ \H
+ Any+
+ \h
+ Any+
+ \V
+ Any+
+ \v
+ Any+
+ \Z
+ Any++
+ \z
+ Any+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/ .+\D .+\d .+\S .+\s .+\W .+\w .+. .+\C .+\R .+\H .+\h .+\V .+\v .+\Z .+\z .+$/BZxs
+------------------------------------------------------------------
+ Bra
+ AllAny+
+ \D
+ AllAny+
+ \d
+ AllAny+
+ \S
+ AllAny+
+ \s
+ AllAny+
+ \W
+ AllAny+
+ \w
+ AllAny+
+ AllAny
+ AllAny+
+ AllAny
+ AllAny+
+ \R
+ AllAny+
+ \H
+ AllAny+
+ \h
+ AllAny+
+ \V
+ AllAny+
+ \v
+ AllAny+
+ \Z
+ AllAny++
+ \z
+ AllAny+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\D+$ \d+$ \S+$ \s+$ \W+$ \w+$ \C+$ \R+$ \H+$ \h+$ \V+$ \v+$ a+$ \n+$ .+$ .+$/BZxm
+------------------------------------------------------------------
+ Bra
+ \D+
+ /m $
+ \d++
+ /m $
+ \S++
+ /m $
+ \s+
+ /m $
+ \W+
+ /m $
+ \w++
+ /m $
+ AllAny+
+ /m $
+ \R+
+ /m $
+ \H+
+ /m $
+ \h+
+ /m $
+ \V+
+ /m $
+ \v+
+ /m $
+ a+
+ /m $
+ \x0a+
+ /m $
+ Any+
+ /m $
+ Any+
+ /m $
+ Ket
+ End
+------------------------------------------------------------------
+
+/(?=a+)a(a+)++a/BZ
+------------------------------------------------------------------
+ Bra
+ Assert
+ a++
+ Ket
+ a
+ CBraPos 1
+ a++
+ KetRpos
+ a
+ Ket
+ End
+------------------------------------------------------------------
+
+/a+(bb|cc)a+(?:bb|cc)a+(?>bb|cc)a+(?:bb|cc)+a+(aa)a+(?:bb|aa)/BZ
+------------------------------------------------------------------
+ Bra
+ a++
+ CBra 1
+ bb
+ Alt
+ cc
+ Ket
+ a++
+ Bra
+ bb
+ Alt
+ cc
+ Ket
+ a++
+ Once_NC
+ bb
+ Alt
+ cc
+ Ket
+ a++
+ Bra
+ bb
+ Alt
+ cc
+ KetRmax
+ a+
+ CBra 2
+ aa
+ Ket
+ a+
+ Bra
+ bb
+ Alt
+ aa
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+/a+(bb|cc)?#a+(?:bb|cc)??#a+(?:bb|cc)?+#a+(?:bb|cc)*#a+(bb|cc)?a#a+(?:aa)?/BZ
+------------------------------------------------------------------
+ Bra
+ a++
+ Brazero
+ CBra 1
+ bb
+ Alt
+ cc
+ Ket
+ #
+ a++
+ Braminzero
+ Bra
+ bb
+ Alt
+ cc
+ Ket
+ #
+ a++
+ Once
+ Brazero
+ Bra
+ bb
+ Alt
+ cc
+ Ket
+ Ket
+ #
+ a++
+ Brazero
+ Bra
+ bb
+ Alt
+ cc
+ KetRmax
+ #
+ a+
+ Brazero
+ CBra 2
+ bb
+ Alt
+ cc
+ Ket
+ a#
+ a+
+ Brazero
+ Bra
+ aa
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+
+/a+(?:bb)?a#a+(?:|||)#a+(?:|b)a#a+(?:|||)?a/BZ
+------------------------------------------------------------------
+ Bra
+ a+
+ Brazero
+ Bra
+ bb
+ Ket
+ a#
+ a++
+ Bra
+ Alt
+ Alt
+ Alt
+ Ket
+ #
+ a+
+ Bra
+ Alt
+ b
+ Ket
+ a#
+ a+
+ Brazero
+ Bra
+ Alt
+ Alt
+ Alt
+ Ket
+ a
+ Ket
+ End
+------------------------------------------------------------------
+
+/[ab]*/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]*+
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aaaa
+
+/[ab]*?/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]*?
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0:
+
+/[ab]?/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]?+
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: a
+
+/[ab]??/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]??
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0:
+
+/[ab]+/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]++
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aaaa
+
+/[ab]+?/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]+?
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: a
+
+/[ab]{2,3}/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]{2,3}+
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aaa
+
+/[ab]{2,3}?/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]{2,3}?
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aa
+
+/[ab]{2,}/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]{2,}+
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aaaa
+
+/[ab]{2,}?/BZ
+------------------------------------------------------------------
+ Bra
+ [ab]{2,}?
+ Ket
+ End
+------------------------------------------------------------------
+ aaaa
+ 0: aa
+
+/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/BZ
+------------------------------------------------------------------
+ Bra
+ \d++
+ \s{0,5}+
+ =
+ \s*+
+ \S?
+ =
+ \w{0,4}+
+ \W*+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-d]{5,12}[e-z0-9]*#[^a-z]+[b-y]*a[2-7]?[^0-9a-z]+/BZ
+------------------------------------------------------------------
+ Bra
+ [a-d]{5,12}+
+ [0-9e-z]*+
+ #
+ [\x00-`{-\xff] (neg)++
+ [b-y]*+
+ a
+ [2-7]?+
+ [\x00-/:-`{-\xff] (neg)++
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-z]*\s#[ \t]?\S#[a-c]*\S#[C-G]+?\d#[4-8]*\D#[4-9,]*\D#[!$]{0,5}\w#[M-Xf-l]+\W#[a-c,]?\W/BZ
+------------------------------------------------------------------
+ Bra
+ [a-z]*+
+ \s
+ #
+ [\x09 ]?+
+ \S
+ #
+ [a-c]*
+ \S
+ #
+ [C-G]++
+ \d
+ #
+ [4-8]*+
+ \D
+ #
+ [,4-9]*
+ \D
+ #
+ [!$]{0,5}+
+ \w
+ #
+ [M-Xf-l]++
+ \W
+ #
+ [,a-c]?
+ \W
+ Ket
+ End
+------------------------------------------------------------------
+
+/a+(aa|bb)*c#a*(bb|cc)*a#a?(bb|cc)*d#[a-f]*(g|hh)*f/BZ
+------------------------------------------------------------------
+ Bra
+ a+
+ Brazero
+ CBra 1
+ aa
+ Alt
+ bb
+ KetRmax
+ c#
+ a*
+ Brazero
+ CBra 2
+ bb
+ Alt
+ cc
+ KetRmax
+ a#
+ a?+
+ Brazero
+ CBra 3
+ bb
+ Alt
+ cc
+ KetRmax
+ d#
+ [a-f]*
+ Brazero
+ CBra 4
+ g
+ Alt
+ hh
+ KetRmax
+ f
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-f]*(g|hh|i)*i#[a-x]{4,}(y{0,6})*y#[a-k]+(ll|mm)+n/BZ
+------------------------------------------------------------------
+ Bra
+ [a-f]*+
+ Brazero
+ CBra 1
+ g
+ Alt
+ hh
+ Alt
+ i
+ KetRmax
+ i#
+ [a-x]{4,}
+ Brazero
+ SCBra 2
+ y{0,6}
+ KetRmax
+ y#
+ [a-k]++
+ CBra 3
+ ll
+ Alt
+ mm
+ KetRmax
+ n
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-f]*(?>gg|hh)+#[a-f]*(?>gg|hh)?#[a-f]*(?>gg|hh)*a#[a-f]*(?>gg|hh)*h/BZ
+------------------------------------------------------------------
+ Bra
+ [a-f]*+
+ Once_NC
+ gg
+ Alt
+ hh
+ KetRmax
+ #
+ [a-f]*+
+ Brazero
+ Once_NC
+ gg
+ Alt
+ hh
+ Ket
+ #
+ [a-f]*
+ Brazero
+ Once_NC
+ gg
+ Alt
+ hh
+ KetRmax
+ a#
+ [a-f]*+
+ Brazero
+ Once_NC
+ gg
+ Alt
+ hh
+ KetRmax
+ h
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-c]*d/DZS
+------------------------------------------------------------------
+ Bra
+ [a-c]*+
+ d
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'd'
+Subject length lower bound = 1
+Starting byte set: a b c d
+
+/[a-c]+d/DZS
+------------------------------------------------------------------
+ Bra
+ [a-c]++
+ d
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'd'
+Subject length lower bound = 2
+Starting byte set: a b c
+
+/[a-c]?d/DZS
+------------------------------------------------------------------
+ Bra
+ [a-c]?+
+ d
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'd'
+Subject length lower bound = 1
+Starting byte set: a b c d
+
+/[a-c]{4,6}d/DZS
+------------------------------------------------------------------
+ Bra
+ [a-c]{4,6}+
+ d
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'd'
+Subject length lower bound = 5
+Starting byte set: a b c
+
+/[a-c]{0,6}d/DZS
+------------------------------------------------------------------
+ Bra
+ [a-c]{0,6}+
+ d
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'd'
+Subject length lower bound = 1
+Starting byte set: a b c d
+
+/-- End of special auto-possessive tests --/
+
+/^A\o{1239}B/
+Failed: non-octal character in \o{} (closing brace missing?) at offset 8
+
+/^A\oB/
+Failed: missing opening brace after \o at offset 3
+
+/^A\x{zz}B/
+Failed: non-hex character in \x{} (closing brace missing?) at offset 5
+
+/^A\x{12Z/
+Failed: non-hex character in \x{} (closing brace missing?) at offset 7
+
+/^A\x{/
+Failed: non-hex character in \x{} (closing brace missing?) at offset 5
+
+/[ab]++/BZO
+------------------------------------------------------------------
+ Bra
+ [ab]++
+ Ket
+ End
+------------------------------------------------------------------
+
+/[^ab]*+/BZO
+------------------------------------------------------------------
+ Bra
+ [\x00-`c-\xff] (neg)*+
+ Ket
+ End
+------------------------------------------------------------------
+
+/a{4}+/BZO
+------------------------------------------------------------------
+ Bra
+ a{4}
+ Ket
+ End
+------------------------------------------------------------------
+
+/a{4}+/BZOi
+------------------------------------------------------------------
+ Bra
+ /i a{4}
+ Ket
+ End
+------------------------------------------------------------------
+
+/[a-[:digit:]]+/
+Failed: invalid range in character class at offset 3
+
+/[A-[:digit:]]+/
+Failed: invalid range in character class at offset 3
+
+/[a-[.xxx.]]+/
+Failed: invalid range in character class at offset 3
+
+/[a-[=xxx=]]+/
+Failed: invalid range in character class at offset 3
+
+/[a-[!xxx!]]+/
+Failed: range out of order in character class at offset 3
+
+/[A-[!xxx!]]+/
+ A]]]
+ 0: A]]]
+
+/[a-\d]+/
+Failed: invalid range in character class at offset 4
+
+/(?<0abc>xx)/
+Failed: group name must start with a non-digit at offset 3
+
+/(?&1abc)xx(?<1abc>y)/
+Failed: group name must start with a non-digit at offset 3
+
+/(?<ab-cd>xx)/
+Failed: syntax error in subpattern name (missing terminator) at offset 5
+
+/(?'0abc'xx)/
+Failed: group name must start with a non-digit at offset 3
+
+/(?P<0abc>xx)/
+Failed: group name must start with a non-digit at offset 4
+
+/\k<5ghj>/
+Failed: group name must start with a non-digit at offset 3
+
+/\k'5ghj'/
+Failed: group name must start with a non-digit at offset 3
+
+/\k{2fgh}/
+Failed: group name must start with a non-digit at offset 3
+
+/(?P=8yuki)/
+Failed: group name must start with a non-digit at offset 4
+
+/\g{4df}/
+Failed: group name must start with a non-digit at offset 3
+
+/(?&1abc)xx(?<1abc>y)/
+Failed: group name must start with a non-digit at offset 3
+
+/(?P>1abc)xx(?<1abc>y)/
+Failed: group name must start with a non-digit at offset 4
+
+/\g'3gh'/
+Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 7
+
+/\g<5fg>/
+Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 7
+
+/(?(<4gh>)abc)/
+Failed: group name must start with a non-digit at offset 4
+
+/(?('4gh')abc)/
+Failed: group name must start with a non-digit at offset 4
+
+/(?(4gh)abc)/
+Failed: malformed number or name after (?( at offset 4
+
+/(?(R&6yh)abc)/
+Failed: group name must start with a non-digit at offset 5
+
+/-- Test the ugly "start or end of word" compatibility syntax --/
+
+/[[:<:]]red[[:>:]]/BZ
+------------------------------------------------------------------
+ Bra
+ \b
+ Assert
+ \w
+ Ket
+ red
+ \b
+ AssertB
+ Reverse
+ \w
+ Ket
+ Ket
+ End
+------------------------------------------------------------------
+ little red riding hood
+ 0: red
+ a /red/ thing
+ 0: red
+ red is a colour
+ 0: red
+ put it all on red
+ 0: red
+ ** Failers
+No match
+ no reduction
+No match
+ Alfred Winifred
+No match
+
+/[a[:<:]] should give error/
+Failed: unknown POSIX class name at offset 4
+
/-- End of testinput2 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput20 b/ext/pcre/pcrelib/testdata/testoutput20
new file mode 100644
index 0000000000..c1b20ee804
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput20
@@ -0,0 +1,24 @@
+/-- These DFA tests are for the handling of characters greater than 255 in
+ 16- or 32-bit, non-UTF mode. --/
+
+/^\x{ffff}+/i
+ \x{ffff}
+ 0: \x{ffff}
+
+/^\x{ffff}?/i
+ \x{ffff}
+ 0: \x{ffff}
+
+/^\x{ffff}*/i
+ \x{ffff}
+ 0: \x{ffff}
+
+/^\x{ffff}{3}/i
+ \x{ffff}\x{ffff}\x{ffff}
+ 0: \x{ffff}\x{ffff}\x{ffff}
+
+/^\x{ffff}{0,3}/i
+ \x{ffff}
+ 0: \x{ffff}
+
+/-- End of testinput20 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput21-16 b/ext/pcre/pcrelib/testdata/testoutput21-16
new file mode 100644
index 0000000000..0e21350f89
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput21-16
@@ -0,0 +1,100 @@
+/-- Tests for reloading pre-compiled patterns. The first one gives an error
+right away, and can be any old pattern compiled in 8-bit mode ("abc" is
+typical). The others require the link size to be 2. */x
+
+<!testsaved8
+Compiled pattern loaded from testsaved8
+No study data
+Error -28 from pcre16_fullinfo(0)
+Running in 16-bit mode but pattern was compiled in 8-bit mode
+
+%-- Generated from:
+ /^[aL](?P<name>(?:[AaLl]+)[^xX-]*?)(?P<other>[\x{150}-\x{250}\x{300}]|
+ [^\x{800}aAs-uS-U\x{d800}-\x{dfff}])++[^#\b\x{500}\x{1000}]{3,5}$
+ /x
+
+ In 16-bit mode with options: S>testdata/saved16LE-1
+ FS>testdata/saved16BE-1
+ In 32-bit mode with options: S>testdata/saved32LE-1
+ FS>testdata/saved32BE-1
+--%x
+
+<!testsaved16LE-1
+Compiled pattern loaded from testsaved16LE-1
+Study data loaded from testsaved16LE-1
+------------------------------------------------------------------
+ 0 134 Bra
+ 2 ^
+ 3 [La]
+ 20 43 CBra 1
+ 23 20 Bra
+ 25 [ALal]+
+ 43 20 Ket
+ 45 [\x00-,.-WY-wy-\xff] (neg)*?
+ 63 43 Ket
+ 65 12 CBraPos 2
+ 68 [\x{150}-\x{250}\x{300}]
+ 77 27 Alt
+ 79 [^AS-Uas-u\x{800}\x{d800}-\x{dfff}]
+104 39 KetRpos
+106 [^\x08#\x{500}\x{1000}]{3,5}
+133 $
+134 134 Ket
+136 End
+------------------------------------------------------------------
+Capturing subpattern count = 2
+Named capturing subpatterns:
+ name 1
+ other 2
+Options: anchored extended
+No first char
+No need char
+Subject length lower bound = 6
+No set of starting bytes
+
+<!testsaved16BE-1
+Compiled pattern loaded from testsaved16BE-1
+Study data loaded from testsaved16BE-1
+------------------------------------------------------------------
+ 0 134 Bra
+ 2 ^
+ 3 [La]
+ 20 43 CBra 1
+ 23 20 Bra
+ 25 [ALal]+
+ 43 20 Ket
+ 45 [\x00-,.-WY-wy-\xff] (neg)*?
+ 63 43 Ket
+ 65 12 CBraPos 2
+ 68 [\x{150}-\x{250}\x{300}]
+ 77 27 Alt
+ 79 [^AS-Uas-u\x{800}\x{d800}-\x{dfff}]
+104 39 KetRpos
+106 [^\x08#\x{500}\x{1000}]{3,5}
+133 $
+134 134 Ket
+136 End
+------------------------------------------------------------------
+Capturing subpattern count = 2
+Named capturing subpatterns:
+ name 1
+ other 2
+Options: anchored extended
+No first char
+No need char
+Subject length lower bound = 6
+No set of starting bytes
+
+<!testsaved32LE-1
+Compiled pattern loaded from testsaved32LE-1
+Study data loaded from testsaved32LE-1
+Error -28 from pcre16_fullinfo(0)
+Running in 16-bit mode but pattern was compiled in 32-bit mode
+
+<!testsaved32BE-1
+Compiled pattern loaded from testsaved32BE-1
+Study data loaded from testsaved32BE-1
+Error -28 from pcre16_fullinfo(0)
+Running in 16-bit mode but pattern was compiled in 32-bit mode
+
+/-- End of testinput21 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput21-32 b/ext/pcre/pcrelib/testdata/testoutput21-32
new file mode 100644
index 0000000000..183487aca1
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput21-32
@@ -0,0 +1,100 @@
+/-- Tests for reloading pre-compiled patterns. The first one gives an error
+right away, and can be any old pattern compiled in 8-bit mode ("abc" is
+typical). The others require the link size to be 2. */x
+
+<!testsaved8
+Compiled pattern loaded from testsaved8
+No study data
+Error -28 from pcre32_fullinfo(0)
+Running in 32-bit mode but pattern was compiled in 8-bit mode
+
+%-- Generated from:
+ /^[aL](?P<name>(?:[AaLl]+)[^xX-]*?)(?P<other>[\x{150}-\x{250}\x{300}]|
+ [^\x{800}aAs-uS-U\x{d800}-\x{dfff}])++[^#\b\x{500}\x{1000}]{3,5}$
+ /x
+
+ In 16-bit mode with options: S>testdata/saved16LE-1
+ FS>testdata/saved16BE-1
+ In 32-bit mode with options: S>testdata/saved32LE-1
+ FS>testdata/saved32BE-1
+--%x
+
+<!testsaved16LE-1
+Compiled pattern loaded from testsaved16LE-1
+Study data loaded from testsaved16LE-1
+Error -28 from pcre32_fullinfo(0)
+Running in 32-bit mode but pattern was compiled in 16-bit mode
+
+<!testsaved16BE-1
+Compiled pattern loaded from testsaved16BE-1
+Study data loaded from testsaved16BE-1
+Error -28 from pcre32_fullinfo(0)
+Running in 32-bit mode but pattern was compiled in 16-bit mode
+
+<!testsaved32LE-1
+Compiled pattern loaded from testsaved32LE-1
+Study data loaded from testsaved32LE-1
+------------------------------------------------------------------
+ 0 94 Bra
+ 2 ^
+ 3 [La]
+ 12 27 CBra 1
+ 15 12 Bra
+ 17 [ALal]+
+ 27 12 Ket
+ 29 [\x00-,.-WY-wy-\xff] (neg)*?
+ 39 27 Ket
+ 41 12 CBraPos 2
+ 44 [\x{150}-\x{250}\x{300}]
+ 53 19 Alt
+ 55 [^AS-Uas-u\x{800}\x{d800}-\x{dfff}]
+ 72 31 KetRpos
+ 74 [^\x08#\x{500}\x{1000}]{3,5}
+ 93 $
+ 94 94 Ket
+ 96 End
+------------------------------------------------------------------
+Capturing subpattern count = 2
+Named capturing subpatterns:
+ name 1
+ other 2
+Options: anchored extended
+No first char
+No need char
+Subject length lower bound = 6
+No set of starting bytes
+
+<!testsaved32BE-1
+Compiled pattern loaded from testsaved32BE-1
+Study data loaded from testsaved32BE-1
+------------------------------------------------------------------
+ 0 94 Bra
+ 2 ^
+ 3 [La]
+ 12 27 CBra 1
+ 15 12 Bra
+ 17 [ALal]+
+ 27 12 Ket
+ 29 [\x00-,.-WY-wy-\xff] (neg)*?
+ 39 27 Ket
+ 41 12 CBraPos 2
+ 44 [\x{150}-\x{250}\x{300}]
+ 53 19 Alt
+ 55 [^AS-Uas-u\x{800}\x{d800}-\x{dfff}]
+ 72 31 KetRpos
+ 74 [^\x08#\x{500}\x{1000}]{3,5}
+ 93 $
+ 94 94 Ket
+ 96 End
+------------------------------------------------------------------
+Capturing subpattern count = 2
+Named capturing subpatterns:
+ name 1
+ other 2
+Options: anchored extended
+No first char
+No need char
+Subject length lower bound = 6
+No set of starting bytes
+
+/-- End of testinput21 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput22-16 b/ext/pcre/pcrelib/testdata/testoutput22-16
new file mode 100644
index 0000000000..f896b13e18
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput22-16
@@ -0,0 +1,81 @@
+/-- Tests for reloading pre-compile patterns with UTF-16 or UTF-32 support. */
+
+%-- Generated from:
+ /(?P<cbra1>[aZ\x{400}-\x{10ffff}]{4,}
+ [\x{f123}\x{10039}\x{20000}-\x{21234}]?|
+ [A-Cx-z\x{100000}-\x{1000a7}\x{101234}])
+ (?<cb2>[^az])/x
+
+ In 16-bit mode with options: S8>testdata/saved16LE-2
+ FS8>testdata/saved16BE-2
+ In 32-bit mode with options: S8>testdata/saved32LE-2
+ FS8>testdata/saved32BE-2
+--%8x
+
+<!testsaved16LE-2
+Compiled pattern loaded from testsaved16LE-2
+Study data loaded from testsaved16LE-2
+------------------------------------------------------------------
+ 0 101 Bra
+ 2 45 CBra 1
+ 5 [Za\x{400}-\x{10ffff}]{4,}
+ 32 [\x{f123}\x{10039}\x{20000}-\x{21234}]?
+ 47 30 Alt
+ 49 [A-Cx-z\x{100000}-\x{1000a7}\x{101234}]
+ 77 75 Ket
+ 79 20 CBra 2
+ 82 [\x00-`b-y{-\xff] (neg)
+ 99 20 Ket
+101 101 Ket
+103 End
+------------------------------------------------------------------
+Capturing subpattern count = 2
+Named capturing subpatterns:
+ cb2 2
+ cbra1 1
+Options: extended utf
+No first char
+No need char
+Subject length lower bound = 2
+No set of starting bytes
+
+<!testsaved16BE-2
+Compiled pattern loaded from testsaved16BE-2
+Study data loaded from testsaved16BE-2
+------------------------------------------------------------------
+ 0 101 Bra
+ 2 45 CBra 1
+ 5 [Za\x{400}-\x{10ffff}]{4,}
+ 32 [\x{f123}\x{10039}\x{20000}-\x{21234}]?
+ 47 30 Alt
+ 49 [A-Cx-z\x{100000}-\x{1000a7}\x{101234}]
+ 77 75 Ket
+ 79 20 CBra 2
+ 82 [\x00-`b-y{-\xff] (neg)
+ 99 20 Ket
+101 101 Ket
+103 End
+------------------------------------------------------------------
+Capturing subpattern count = 2
+Named capturing subpatterns:
+ cb2 2
+ cbra1 1
+Options: extended utf
+No first char
+No need char
+Subject length lower bound = 2
+No set of starting bytes
+
+<!testsaved32LE-2
+Compiled pattern loaded from testsaved32LE-2
+Study data loaded from testsaved32LE-2
+Error -28 from pcre16_fullinfo(0)
+Running in 16-bit mode but pattern was compiled in 32-bit mode
+
+<!testsaved32BE-2
+Compiled pattern loaded from testsaved32BE-2
+Study data loaded from testsaved32BE-2
+Error -28 from pcre16_fullinfo(0)
+Running in 16-bit mode but pattern was compiled in 32-bit mode
+
+/-- End of testinput22 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput22-32 b/ext/pcre/pcrelib/testdata/testoutput22-32
new file mode 100644
index 0000000000..783926b821
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput22-32
@@ -0,0 +1,81 @@
+/-- Tests for reloading pre-compile patterns with UTF-16 or UTF-32 support. */
+
+%-- Generated from:
+ /(?P<cbra1>[aZ\x{400}-\x{10ffff}]{4,}
+ [\x{f123}\x{10039}\x{20000}-\x{21234}]?|
+ [A-Cx-z\x{100000}-\x{1000a7}\x{101234}])
+ (?<cb2>[^az])/x
+
+ In 16-bit mode with options: S8>testdata/saved16LE-2
+ FS8>testdata/saved16BE-2
+ In 32-bit mode with options: S8>testdata/saved32LE-2
+ FS8>testdata/saved32BE-2
+--%8x
+
+<!testsaved16LE-2
+Compiled pattern loaded from testsaved16LE-2
+Study data loaded from testsaved16LE-2
+Error -28 from pcre32_fullinfo(0)
+Running in 32-bit mode but pattern was compiled in 16-bit mode
+
+<!testsaved16BE-2
+Compiled pattern loaded from testsaved16BE-2
+Study data loaded from testsaved16BE-2
+Error -28 from pcre32_fullinfo(0)
+Running in 32-bit mode but pattern was compiled in 16-bit mode
+
+<!testsaved32LE-2
+Compiled pattern loaded from testsaved32LE-2
+Study data loaded from testsaved32LE-2
+------------------------------------------------------------------
+ 0 70 Bra
+ 2 33 CBra 1
+ 5 [Za\x{400}-\x{10ffff}]{4,}
+ 23 [\x{f123}\x{10039}\x{20000}-\x{21234}]?
+ 35 19 Alt
+ 37 [A-Cx-z\x{100000}-\x{1000a7}\x{101234}]
+ 54 52 Ket
+ 56 12 CBra 2
+ 59 [\x00-`b-y{-\xff] (neg)
+ 68 12 Ket
+ 70 70 Ket
+ 72 End
+------------------------------------------------------------------
+Capturing subpattern count = 2
+Named capturing subpatterns:
+ cb2 2
+ cbra1 1
+Options: extended utf
+No first char
+No need char
+Subject length lower bound = 2
+No set of starting bytes
+
+<!testsaved32BE-2
+Compiled pattern loaded from testsaved32BE-2
+Study data loaded from testsaved32BE-2
+------------------------------------------------------------------
+ 0 70 Bra
+ 2 33 CBra 1
+ 5 [Za\x{400}-\x{10ffff}]{4,}
+ 23 [\x{f123}\x{10039}\x{20000}-\x{21234}]?
+ 35 19 Alt
+ 37 [A-Cx-z\x{100000}-\x{1000a7}\x{101234}]
+ 54 52 Ket
+ 56 12 CBra 2
+ 59 [\x00-`b-y{-\xff] (neg)
+ 68 12 Ket
+ 70 70 Ket
+ 72 End
+------------------------------------------------------------------
+Capturing subpattern count = 2
+Named capturing subpatterns:
+ cb2 2
+ cbra1 1
+Options: extended utf
+No first char
+No need char
+Subject length lower bound = 2
+No set of starting bytes
+
+/-- End of testinput22 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput23 b/ext/pcre/pcrelib/testdata/testoutput23
new file mode 100644
index 0000000000..6f5384c34e
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput23
@@ -0,0 +1,46 @@
+/-- Tests for the 16-bit library only */
+
+< forbid 8W
+
+/-- Check maximum non-UTF character size --/
+
+/\x{ffff}/
+ A\x{ffff}B
+ 0: \x{ffff}
+
+/\x{10000}/
+Failed: character value in \x{} or \o{} is too large at offset 8
+
+/\o{20000}/
+
+/-- Check character ranges --/
+
+/[\H]/BZSI
+------------------------------------------------------------------
+ Bra
+ [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffff}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/[\V]/BZSI
+------------------------------------------------------------------
+ Bra
+ [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{ffff}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/-- End of testinput23 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput24 b/ext/pcre/pcrelib/testdata/testoutput24
new file mode 100644
index 0000000000..0714a0fe15
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput24
@@ -0,0 +1,13 @@
+/-- Tests for the 16-bit library with UTF-16 support only */
+
+< forbid W
+
+/bad/8
+ \x{d800}
+Error -10 (bad UTF-16 string) offset=0 reason=1
+
+/short/8
+ \P\P\x{d800}
+Error -25 (short UTF-16 string) offset=0 reason=1
+
+/-- End of testinput24 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput25 b/ext/pcre/pcrelib/testdata/testoutput25
new file mode 100644
index 0000000000..7ad3378368
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput25
@@ -0,0 +1,93 @@
+/-- Tests for the 32-bit library only */
+
+< forbid 8w
+
+/-- Check maximum character size --/
+
+/\x{110000}/
+
+/\x{7fffffff}/
+
+/\x{80000000}/
+
+/\x{ffffffff}/
+
+/\x{100000000}/
+Failed: character value in \x{} or \o{} is too large at offset 12
+
+/\o{17777777777}/
+
+/\o{20000000000}/
+
+/\o{37777777777}/
+
+/\o{40000000000}/
+Failed: character value in \x{} or \o{} is too large at offset 14
+
+/\x{7fffffff}\x{7fffffff}/I
+Capturing subpattern count = 0
+No options
+First char = \x{7fffffff}
+Need char = \x{7fffffff}
+
+/\x{80000000}\x{80000000}/I
+Capturing subpattern count = 0
+No options
+First char = \x{80000000}
+Need char = \x{80000000}
+
+/\x{ffffffff}\x{ffffffff}/I
+Capturing subpattern count = 0
+No options
+First char = \x{ffffffff}
+Need char = \x{ffffffff}
+
+/-- Non-UTF characters --/
+
+/\C{2,3}/
+ \x{400000}\x{400001}\x{400002}\x{400003}
+ 0: \x{400000}\x{400001}\x{400002}
+
+/\x{400000}\x{800000}/iDZ
+------------------------------------------------------------------
+ Bra
+ /i \x{400000}\x{800000}
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: caseless
+First char = \x{400000}
+Need char = \x{800000}
+
+/-- Check character ranges --/
+
+/[\H]/BZSI
+------------------------------------------------------------------
+ Bra
+ [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{ffffffff}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/[\V]/BZSI
+------------------------------------------------------------------
+ Bra
+ [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{ffffffff}]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+No set of starting bytes
+
+/-- End of testinput25 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput26 b/ext/pcre/pcrelib/testdata/testoutput26
new file mode 100644
index 0000000000..28f8d42a5e
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutput26
@@ -0,0 +1,17 @@
+/-- Tests for the 32-bit library with UTF-32 support only */
+
+< forbid W
+
+/-- Non-UTF characters --/
+
+/\x{110000}/8
+Failed: character value in \x{} or \o{} is too large at offset 9
+
+/\o{4200000}/8
+Failed: character value in \x{} or \o{} is too large at offset 10
+
+/\C/8
+ \x{110000}
+Error -10 (bad UTF-32 string) offset=0 reason=3
+
+/-- End of testinput26 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput3 b/ext/pcre/pcrelib/testdata/testoutput3
index 7b0a3e926e..12ffc9911b 100644
--- a/ext/pcre/pcrelib/testdata/testoutput3
+++ b/ext/pcre/pcrelib/testdata/testoutput3
@@ -1,6 +1,8 @@
/-- This set of tests checks local-specific features, using the fr_FR locale.
It is not Perl-compatible. There is different version called wintestinput3
f or use on Windows, where the locale is called "french". --/
+
+< forbid 8W
/^[\w]+/
*** Failers
diff --git a/ext/pcre/pcrelib/testdata/testoutput4 b/ext/pcre/pcrelib/testdata/testoutput4
index 2082721c56..0dbec4ecca 100644
--- a/ext/pcre/pcrelib/testdata/testoutput4
+++ b/ext/pcre/pcrelib/testdata/testoutput4
@@ -1,6 +1,8 @@
/-- This set of tests is for UTF support, excluding Unicode properties. It is
compatible with all versions of Perl >= 5.10 and both the 8-bit and 16-bit
PCRE libraries. --/
+
+< forbid 9?=ABCDEFfGILMNPTUWXZ<
/a.b/8
acb
@@ -1091,4 +1093,174 @@ MK: a\x{1234}b
0: a
MK: a\x{a3}b
+/-- Noncharacters --/
+
+/./8
+ \x{fffe}
+ 0: \x{fffe}
+ \x{ffff}
+ 0: \x{ffff}
+ \x{1fffe}
+ 0: \x{1fffe}
+ \x{1ffff}
+ 0: \x{1ffff}
+ \x{2fffe}
+ 0: \x{2fffe}
+ \x{2ffff}
+ 0: \x{2ffff}
+ \x{3fffe}
+ 0: \x{3fffe}
+ \x{3ffff}
+ 0: \x{3ffff}
+ \x{4fffe}
+ 0: \x{4fffe}
+ \x{4ffff}
+ 0: \x{4ffff}
+ \x{5fffe}
+ 0: \x{5fffe}
+ \x{5ffff}
+ 0: \x{5ffff}
+ \x{6fffe}
+ 0: \x{6fffe}
+ \x{6ffff}
+ 0: \x{6ffff}
+ \x{7fffe}
+ 0: \x{7fffe}
+ \x{7ffff}
+ 0: \x{7ffff}
+ \x{8fffe}
+ 0: \x{8fffe}
+ \x{8ffff}
+ 0: \x{8ffff}
+ \x{9fffe}
+ 0: \x{9fffe}
+ \x{9ffff}
+ 0: \x{9ffff}
+ \x{afffe}
+ 0: \x{afffe}
+ \x{affff}
+ 0: \x{affff}
+ \x{bfffe}
+ 0: \x{bfffe}
+ \x{bffff}
+ 0: \x{bffff}
+ \x{cfffe}
+ 0: \x{cfffe}
+ \x{cffff}
+ 0: \x{cffff}
+ \x{dfffe}
+ 0: \x{dfffe}
+ \x{dffff}
+ 0: \x{dffff}
+ \x{efffe}
+ 0: \x{efffe}
+ \x{effff}
+ 0: \x{effff}
+ \x{ffffe}
+ 0: \x{ffffe}
+ \x{fffff}
+ 0: \x{fffff}
+ \x{10fffe}
+ 0: \x{10fffe}
+ \x{10ffff}
+ 0: \x{10ffff}
+ \x{fdd0}
+ 0: \x{fdd0}
+ \x{fdd1}
+ 0: \x{fdd1}
+ \x{fdd2}
+ 0: \x{fdd2}
+ \x{fdd3}
+ 0: \x{fdd3}
+ \x{fdd4}
+ 0: \x{fdd4}
+ \x{fdd5}
+ 0: \x{fdd5}
+ \x{fdd6}
+ 0: \x{fdd6}
+ \x{fdd7}
+ 0: \x{fdd7}
+ \x{fdd8}
+ 0: \x{fdd8}
+ \x{fdd9}
+ 0: \x{fdd9}
+ \x{fdda}
+ 0: \x{fdda}
+ \x{fddb}
+ 0: \x{fddb}
+ \x{fddc}
+ 0: \x{fddc}
+ \x{fddd}
+ 0: \x{fddd}
+ \x{fdde}
+ 0: \x{fdde}
+ \x{fddf}
+ 0: \x{fddf}
+ \x{fde0}
+ 0: \x{fde0}
+ \x{fde1}
+ 0: \x{fde1}
+ \x{fde2}
+ 0: \x{fde2}
+ \x{fde3}
+ 0: \x{fde3}
+ \x{fde4}
+ 0: \x{fde4}
+ \x{fde5}
+ 0: \x{fde5}
+ \x{fde6}
+ 0: \x{fde6}
+ \x{fde7}
+ 0: \x{fde7}
+ \x{fde8}
+ 0: \x{fde8}
+ \x{fde9}
+ 0: \x{fde9}
+ \x{fdea}
+ 0: \x{fdea}
+ \x{fdeb}
+ 0: \x{fdeb}
+ \x{fdec}
+ 0: \x{fdec}
+ \x{fded}
+ 0: \x{fded}
+ \x{fdee}
+ 0: \x{fdee}
+ \x{fdef}
+ 0: \x{fdef}
+
+/^\d*\w{4}/8
+ 1234
+ 0: 1234
+ 123
+No match
+
+/^[^b]*\w{4}/8
+ aaaa
+ 0: aaaa
+ aaa
+No match
+
+/^[^b]*\w{4}/8i
+ aaaa
+ 0: aaaa
+ aaa
+No match
+
+/^\x{100}*.{4}/8
+ \x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}\x{100}
+ \x{100}\x{100}\x{100}
+No match
+
+/^\x{100}*.{4}/8i
+ \x{100}\x{100}\x{100}\x{100}
+ 0: \x{100}\x{100}\x{100}\x{100}
+ \x{100}\x{100}\x{100}
+No match
+
+/^a+[a\x{200}]/8
+ aa
+ 0: aa
+
/-- End of testinput4 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput5 b/ext/pcre/pcrelib/testdata/testoutput5
index 0e840540c4..3fa581052e 100644
--- a/ext/pcre/pcrelib/testdata/testoutput5
+++ b/ext/pcre/pcrelib/testdata/testoutput5
@@ -1,26 +1,47 @@
/-- This set of tests checks the API, internals, and non-Perl stuff for UTF
support, excluding Unicode properties. However, tests that give different
results in 8-bit and 16-bit modes are excluded (see tests 16 and 17). --/
+
+< forbid W
/\x{110000}/8DZ
-Failed: character value in \x{...} sequence is too large at offset 9
+Failed: character value in \x{} or \o{} is too large at offset 9
+
+/\o{4200000}/8DZ
+Failed: character value in \x{} or \o{} is too large at offset 10
/\x{ffffffff}/8
-Failed: character value in \x{...} sequence is too large at offset 11
+Failed: character value in \x{} or \o{} is too large at offset 11
+
+/\o{37777777777}/8
+Failed: character value in \x{} or \o{} is too large at offset 14
/\x{100000000}/8
-Failed: character value in \x{...} sequence is too large at offset 12
+Failed: character value in \x{} or \o{} is too large at offset 12
+
+/\o{77777777777}/8
+Failed: character value in \x{} or \o{} is too large at offset 14
/\x{d800}/8
Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
+/\o{154000}/8
+Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 9
+
/\x{dfff}/8
Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
+/\o{157777}/8
+Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 9
+
/\x{d7ff}/8
+/\o{153777}/8
+
/\x{e000}/8
+/\o{170000}/8
+
/^\x{100}a\x{1234}/8
\x{100}a\x{1234}bcd
0: \x{100}a\x{1234}
@@ -146,11 +167,12 @@ No match
/\x{100}*/8DZ
------------------------------------------------------------------
Bra
- \x{100}*
+ \x{100}*+
Ket
End
------------------------------------------------------------------
Capturing subpattern count = 0
+May match empty string
Options: utf
No first char
No need char
@@ -159,7 +181,7 @@ No need char
------------------------------------------------------------------
Bra
a
- \x{100}*
+ \x{100}*+
Ket
End
------------------------------------------------------------------
@@ -172,7 +194,7 @@ No need char
------------------------------------------------------------------
Bra
ab
- \x{100}*
+ \x{100}*+
Ket
End
------------------------------------------------------------------
@@ -373,6 +395,7 @@ Need char = 'z'
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
Options: utf
No first char
No need char
@@ -404,6 +427,7 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
Options: utf
No first char
No need char
@@ -424,6 +448,7 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
Options: utf
No first char
No need char
@@ -455,6 +480,7 @@ No need char
End
------------------------------------------------------------------
Capturing subpattern count = 2
+May match empty string
Options: utf
No first char
No need char
@@ -768,7 +794,7 @@ No match
/[\h]{3,}/8BZ
------------------------------------------------------------------
Bra
- [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]{3,}
+ [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}]{3,}+
Ket
End
------------------------------------------------------------------
@@ -1572,7 +1598,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
/[\h\x{e000}]+/8BZ
------------------------------------------------------------------
Bra
- [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{e000}]+
+ [\x09 \xa0\x{1680}\x{180e}\x{2000}-\x{200a}\x{202f}\x{205f}\x{3000}\x{e000}]++
Ket
End
------------------------------------------------------------------
@@ -1594,7 +1620,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
/[\H\x{d7ff}]+/8BZ
------------------------------------------------------------------
Bra
- [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}\x{d7ff}]+
+ [\x00-\x08\x0a-\x1f!-\x9f\x{a1}-\x{167f}\x{1681}-\x{180d}\x{180f}-\x{1fff}\x{200b}-\x{202e}\x{2030}-\x{205e}\x{2060}-\x{2fff}\x{3001}-\x{10ffff}\x{d7ff}]++
Ket
End
------------------------------------------------------------------
@@ -1616,7 +1642,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
/[\v\x{e000}]+/8BZ
------------------------------------------------------------------
Bra
- [\x0a-\x0d\x85\x{2028}-\x{2029}\x{e000}]+
+ [\x0a-\x0d\x85\x{2028}-\x{2029}\x{e000}]++
Ket
End
------------------------------------------------------------------
@@ -1634,7 +1660,7 @@ Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7
/[\V\x{d7ff}]+/8BZ
------------------------------------------------------------------
Bra
- [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]+
+ [\x00-\x09\x0e-\x84\x{86}-\x{2027}\x{202a}-\x{10ffff}\x{d7ff}]++
Ket
End
------------------------------------------------------------------
@@ -1808,20 +1834,18 @@ Partial match: \x{0d}\x{0d}
/i [^\x{8000}]*
/i [^\x{7fff}]{2}
/i [^\x{7fff}]{0,7}?
- Once
/i [^\x{fffff}]{5}
- /i [^\x{fffff}]?
- Ket
+ /i [^\x{fffff}]?+
Ket
End
------------------------------------------------------------------
/(?<=\x{1234}\x{1234})\bxy/I8
Capturing subpattern count = 0
+Max lookbehind = 2
Options: utf
First char = 'x'
Need char = 'y'
-Max lookbehind = 2
/(?<!^)ETA/8
ETA
@@ -1846,4 +1870,16 @@ No match
/\ud800/<JS>8
Failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 5
+/^a+[a\x{200}]/8BZ
+------------------------------------------------------------------
+ Bra
+ ^
+ a+
+ [a\x{200}]
+ Ket
+ End
+------------------------------------------------------------------
+ aa
+ 0: aa
+
/-- End of testinput5 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput6 b/ext/pcre/pcrelib/testdata/testoutput6
index 0182746168..6c42fce1a5 100644
--- a/ext/pcre/pcrelib/testdata/testoutput6
+++ b/ext/pcre/pcrelib/testdata/testoutput6
@@ -1,5 +1,7 @@
/-- This set of tests is for Unicode property support. It is compatible with
Perl >= 5.15. --/
+
+< forbid 9?=ABCDEFfGILMNPTUXZ<
/^\pC\pL\pM\pN\pP\pS\pZ</8
\x7f\x{c0}\x{30f}\x{660}\x{66c}\x{f01}\x{1680}<
@@ -543,16 +545,6 @@ No match
abc
No match
-/\p{Lu}/8i
- A
- 0: A
- aZ
- 0: Z
- ** Failers
- 0: F
- abc
-No match
-
/\p{Ll}/8
a
0: a
@@ -727,6 +719,8 @@ No match
0: \x{6e9}
\x{060b}
0: \x{60b}
+ \x{061c}
+ 0: \x{61c}
** Failers
No match
X\x{06e9}
@@ -1310,7 +1304,7 @@ No match
/^>\s+/8W
>\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b}
- 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{09}
+ 0: > \x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{09}\x{0b}
/^>\pZ+/8W
>\x{20}\x{a0}\x{1680}\x{2028}\x{2029}\x{202f}\x{9}\x{b}
@@ -1338,15 +1332,15 @@ No match
/^[[:graph:]]*/8W
A\x{a1}\x{a0}
- 0: A
+ 0: A\x{a1}
/^[[:print:]]*/8W
A z\x{a0}\x{a1}
- 0: A z
+ 0: A z\x{a0}\x{a1}
/^[[:punct:]]*/8W
.+\x{a1}\x{a0}
- 0: .+
+ 0: .+\x{a1}
/\p{Zs}*?\R/
** Failers
@@ -1548,6 +1542,19 @@ No match
0: \x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}\x{1111}\x{ae4c}X
0+
+/\X*Z/8Y
+ A\x{300}
+No match
+
+/\X*(.)/8Y
+ A\x{1111}\x{ae4c}\x{1169}
+ 0: A\x{1111}
+ 1: \x{1111}
+
+/\X?abc/8Y
+\xff\x7f\x00\x00\x03\x00\x41\xcc\x80\x41\x{300}\x61\x62\x63\x00\>06\?
+ 0: A\x{300}abc
+
/-- --/
/\x{1e9e}+/8i
@@ -2134,4 +2141,308 @@ No match
\x{0053}\x{0073}\x{017f}
0: Ss\x{17f}
+/^\p{Any}*\d{4}/8
+ 1234
+ 0: 1234
+ 123
+No match
+
+/^\X*\w{4}/8
+ 1234
+ 0: 1234
+ 123
+No match
+
+/^A\s+Z/8W
+ A\x{2005}Z
+ 0: A\x{2005}Z
+ A\x{85}\x{180e}\x{2005}Z
+ 0: A\x{85}\x{180e}\x{2005}Z
+
+/^A[\s]+Z/8W
+ A\x{2005}Z
+ 0: A\x{2005}Z
+ A\x{85}\x{180e}\x{2005}Z
+ 0: A\x{85}\x{180e}\x{2005}Z
+
+/^[[:graph:]]+$/8W
+ Letter:ABC
+ 0: Letter:ABC
+ Mark:\x{300}\x{1d172}\x{1d17b}
+ 0: Mark:\x{300}\x{1d172}\x{1d17b}
+ Number:9\x{660}
+ 0: Number:9\x{660}
+ Punctuation:\x{66a},;
+ 0: Punctuation:\x{66a},;
+ Symbol:\x{6de}<>\x{fffc}
+ 0: Symbol:\x{6de}<>\x{fffc}
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ 0: Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ 0: \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ 0: \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ 0: \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ 0: \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ \x{feff}
+ 0: \x{feff}
+ \x{fff9}\x{fffa}\x{fffb}
+ 0: \x{fff9}\x{fffa}\x{fffb}
+ \x{110bd}
+ 0: \x{110bd}
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ 0: \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ \x{e0001}
+ 0: \x{e0001}
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+ 0: \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+ ** Failers
+No match
+ \x{09}
+No match
+ \x{0a}
+No match
+ \x{1D}
+No match
+ \x{20}
+No match
+ \x{85}
+No match
+ \x{a0}
+No match
+ \x{61c}
+No match
+ \x{1680}
+No match
+ \x{180e}
+No match
+ \x{2028}
+No match
+ \x{2029}
+No match
+ \x{202f}
+No match
+ \x{2065}
+No match
+ \x{2066}
+No match
+ \x{2067}
+No match
+ \x{2068}
+No match
+ \x{2069}
+No match
+ \x{3000}
+No match
+ \x{e0002}
+No match
+ \x{e001f}
+No match
+ \x{e0080}
+No match
+
+/^[[:print:]]+$/8W
+ Space: \x{a0}
+ 0: Space: \x{a0}
+ \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005}
+ 0: \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005}
+ \x{2006}\x{2007}\x{2008}\x{2009}\x{200a}
+ 0: \x{2006}\x{2007}\x{2008}\x{2009}\x{200a}
+ \x{202f}\x{205f}
+ 0: \x{202f}\x{205f}
+ \x{3000}
+ 0: \x{3000}
+ Letter:ABC
+ 0: Letter:ABC
+ Mark:\x{300}\x{1d172}\x{1d17b}
+ 0: Mark:\x{300}\x{1d172}\x{1d17b}
+ Number:9\x{660}
+ 0: Number:9\x{660}
+ Punctuation:\x{66a},;
+ 0: Punctuation:\x{66a},;
+ Symbol:\x{6de}<>\x{fffc}
+ 0: Symbol:\x{6de}<>\x{fffc}
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ 0: Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+ \x{180e}
+ 0: \x{180e}
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ 0: \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ 0: \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+ \x{202f}
+ 0: \x{202f}
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ 0: \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ 0: \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+ \x{feff}
+ 0: \x{feff}
+ \x{fff9}\x{fffa}\x{fffb}
+ 0: \x{fff9}\x{fffa}\x{fffb}
+ \x{110bd}
+ 0: \x{110bd}
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ 0: \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+ \x{e0001}
+ 0: \x{e0001}
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+ 0: \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+ ** Failers
+ 0: ** Failers
+ \x{09}
+No match
+ \x{1D}
+No match
+ \x{85}
+No match
+ \x{61c}
+No match
+ \x{2028}
+No match
+ \x{2029}
+No match
+ \x{2065}
+No match
+ \x{2066}
+No match
+ \x{2067}
+No match
+ \x{2068}
+No match
+ \x{2069}
+No match
+ \x{e0002}
+No match
+ \x{e001f}
+No match
+ \x{e0080}
+No match
+
+/^[[:punct:]]+$/8W
+ \$+<=>^`|~
+ 0: $+<=>^`|~
+ !\"#%&'()*,-./:;?@[\\]_{}
+ 0: !"#%&'()*,-./:;?@[\]_{}
+ \x{a1}\x{a7}
+ 0: \x{a1}\x{a7}
+ \x{37e}
+ 0: \x{37e}
+ ** Failers
+No match
+ abcde
+No match
+
+/^[[:^graph:]]+$/8W
+ \x{09}\x{0a}\x{1D}\x{20}\x{85}\x{a0}\x{61c}\x{1680}\x{180e}
+ 0: \x{09}\x{0a}\x{1d} \x{85}\x{a0}\x{61c}\x{1680}\x{180e}
+ \x{2028}\x{2029}\x{202f}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}
+ 0: \x{2028}\x{2029}\x{202f}\x{2065}\x{2066}\x{2067}\x{2068}\x{2069}
+ \x{3000}\x{e0002}\x{e001f}\x{e0080}
+ 0: \x{3000}\x{e0002}\x{e001f}\x{e0080}
+ ** Failers
+No match
+ Letter:ABC
+No match
+ Mark:\x{300}\x{1d172}\x{1d17b}
+No match
+ Number:9\x{660}
+No match
+ Punctuation:\x{66a},;
+No match
+ Symbol:\x{6de}<>\x{fffc}
+No match
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+No match
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+No match
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+No match
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+No match
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+No match
+ \x{feff}
+No match
+ \x{fff9}\x{fffa}\x{fffb}
+No match
+ \x{110bd}
+No match
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+No match
+ \x{e0001}
+No match
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+No match
+
+/^[[:^print:]]+$/8W
+ \x{09}\x{1D}\x{85}\x{61c}\x{2028}\x{2029}\x{2065}\x{2066}\x{2067}
+ 0: \x{09}\x{1d}\x{85}\x{61c}\x{2028}\x{2029}\x{2065}\x{2066}\x{2067}
+ \x{2068}\x{2069}\x{e0002}\x{e001f}\x{e0080}
+ 0: \x{2068}\x{2069}\x{e0002}\x{e001f}\x{e0080}
+ ** Failers
+No match
+ Space: \x{a0}
+No match
+ \x{1680}\x{2000}\x{2001}\x{2002}\x{2003}\x{2004}\x{2005}
+No match
+ \x{2006}\x{2007}\x{2008}\x{2009}\x{200a}
+No match
+ \x{202f}\x{205f}
+No match
+ \x{3000}
+No match
+ Letter:ABC
+No match
+ Mark:\x{300}\x{1d172}\x{1d17b}
+No match
+ Number:9\x{660}
+No match
+ Punctuation:\x{66a},;
+No match
+ Symbol:\x{6de}<>\x{fffc}
+No match
+ Cf-property:\x{ad}\x{600}\x{601}\x{602}\x{603}\x{604}\x{6dd}\x{70f}
+No match
+ \x{180e}
+No match
+ \x{200b}\x{200c}\x{200d}\x{200e}\x{200f}
+No match
+ \x{202a}\x{202b}\x{202c}\x{202d}\x{202e}
+No match
+ \x{202f}
+No match
+ \x{2060}\x{2061}\x{2062}\x{2063}\x{2064}
+No match
+ \x{206a}\x{206b}\x{206c}\x{206d}\x{206e}\x{206f}
+No match
+ \x{feff}
+No match
+ \x{fff9}\x{fffa}\x{fffb}
+No match
+ \x{110bd}
+No match
+ \x{1d173}\x{1d174}\x{1d175}\x{1d176}\x{1d177}\x{1d178}\x{1d179}\x{1d17a}
+No match
+ \x{e0001}
+No match
+ \x{e0020}\x{e0030}\x{e0040}\x{e0050}\x{e0060}\x{e0070}\x{e007f}
+No match
+
+/^[[:^punct:]]+$/8W
+ abcde
+ 0: abcde
+ ** Failers
+No match
+ \$+<=>^`|~
+No match
+ !\"#%&'()*,-./:;?@[\\]_{}
+No match
+ \x{a1}\x{a7}
+No match
+ \x{37e}
+No match
+
/-- End of testinput6 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput7 b/ext/pcre/pcrelib/testdata/testoutput7
index 4f8b7b9bf3..45ac72fd8d 100644
--- a/ext/pcre/pcrelib/testdata/testoutput7
+++ b/ext/pcre/pcrelib/testdata/testoutput7
@@ -78,7 +78,7 @@ No need char
/[\p{Nd}+-]+/8DZ
------------------------------------------------------------------
Bra
- [+\-\p{Nd}]+
+ [+\-\p{Nd}]++
Ket
End
------------------------------------------------------------------
@@ -270,6 +270,20 @@ No need char
End
------------------------------------------------------------------
+/^\p{Cf}/8
+ \x{180e}
+ 0: \x{180e}
+ \x{061c}
+ 0: \x{61c}
+ \x{2066}
+ 0: \x{2066}
+ \x{2067}
+ 0: \x{2067}
+ \x{2068}
+ 0: \x{2068}
+ \x{2069}
+ 0: \x{2069}
+
/^\p{Cs}/8
\?\x{dfff}
0: \x{dfff}
@@ -278,6 +292,22 @@ No match
\x{09f}
No match
+/^\p{Mn}/8
+ \x{1a1b}
+ 0: \x{1a1b}
+
+/^\p{Pe}/8
+ \x{2309}
+ 0: \x{2309}
+ \x{230b}
+ 0: \x{230b}
+
+/^\p{Ps}/8
+ \x{2308}
+ 0: \x{2308}
+ \x{230a}
+ 0: \x{230a}
+
/^\p{Sc}+/8
$\x{a2}\x{a3}\x{a4}\x{a5}\x{a6}
0: $\x{a2}\x{a3}\x{a4}\x{a5}
@@ -297,8 +327,6 @@ No match
0: \x{a0}
\x{1680}
0: \x{1680}
- \x{180e}
- 0: \x{180e}
\x{2000}
0: \x{2000}
\x{2001}
@@ -310,8 +338,9 @@ No match
\x{200d}
No match
-/-- These four are here rather than in test 6 because Perl has problems with
- the negative versions of the properties. --/
+/-- These are here rather than in test 6 because Perl has problems with
+ the negative versions of the properties and behaves has changed how
+ it behaves for caseless matching. --/
/\p{^Lu}/8i
1234
@@ -351,6 +380,16 @@ No match
\x{1d00}
No match
+/\p{Lu}/8i
+ A
+ 0: A
+ aZ
+ 0: Z
+ ** Failers
+ 0: F
+ abc
+No match
+
/[\x{c0}\x{391}]/8i
\x{c0}
0: \x{c0}
@@ -501,7 +540,7 @@ No match
/^>\p{Xsp}+/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
/^>\p{Xsp}+?/8
>\x{1680}\x{2028}\x{0b}
@@ -509,11 +548,11 @@ No match
/^>\p{Xsp}*/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
/^>\p{Xsp}{2,9}/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
/^>\p{Xsp}{2,9}?/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
@@ -525,7 +564,7 @@ No match
/^>[\p{Xsp}]+/8
> \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
- 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}
+ 0: > \x{09}\x{0a}\x{0c}\x{0d}\x{a0}\x{1680}\x{2028}\x{0b}
/^>\p{Xps}/8
>\x{1680}\x{2028}\x{0b}
@@ -820,7 +859,7 @@ No match
/[[:graph:]]/WBZ
------------------------------------------------------------------
Bra
- [!-~]
+ [[:graph:]]
Ket
End
------------------------------------------------------------------
@@ -828,7 +867,7 @@ No match
/[[:print:]]/WBZ
------------------------------------------------------------------
Bra
- [ -~]
+ [[:print:]]
Ket
End
------------------------------------------------------------------
@@ -836,7 +875,7 @@ No match
/[[:punct:]]/WBZ
------------------------------------------------------------------
Bra
- [!-/:-@[-`{-~]
+ [[:punct:]]
Ket
End
------------------------------------------------------------------
@@ -910,7 +949,7 @@ No match
/[[:^alpha:][:^cntrl:]]+/8WBZ
------------------------------------------------------------------
Bra
- [ -~\x80-\xff\P{L}]+
+ [ -~\x80-\xff\P{L}]++
Ket
End
------------------------------------------------------------------
@@ -922,7 +961,7 @@ No match
/[[:^cntrl:][:^alpha:]]+/8WBZ
------------------------------------------------------------------
Bra
- [ -~\x80-\xff\P{L}]+
+ [ -~\x80-\xff\P{L}]++
Ket
End
------------------------------------------------------------------
@@ -934,7 +973,7 @@ No match
/[[:alpha:]]+/8WBZ
------------------------------------------------------------------
Bra
- [\p{L}]+
+ [\p{L}]++
Ket
End
------------------------------------------------------------------
@@ -944,7 +983,7 @@ No match
/[[:^alpha:]\S]+/8WBZ
------------------------------------------------------------------
Bra
- [\P{L}\P{Xsp}]+
+ [\P{L}\P{Xsp}]++
Ket
End
------------------------------------------------------------------
@@ -956,7 +995,7 @@ No match
/[^\d]+/8WBZ
------------------------------------------------------------------
Bra
- [^\p{Nd}]+
+ [^\p{Nd}]++
Ket
End
------------------------------------------------------------------
@@ -1070,8 +1109,8 @@ No match
prop Nd
B+
prop N *+
- B+
- prop Nd *
+ B++
+ prop Nd *+
Ket
End
------------------------------------------------------------------
@@ -1347,7 +1386,7 @@ Need char = 'B' (caseless)
/[\x{3a3}]+/8iBZ
------------------------------------------------------------------
Bra
- clist 03a3 03c2 03c3 +
+ clist 03a3 03c2 03c3 ++
Ket
End
------------------------------------------------------------------
@@ -1355,7 +1394,7 @@ Need char = 'B' (caseless)
/[^\x{3a3}]+/8iBZ
------------------------------------------------------------------
Bra
- not clist 03a3 03c2 03c3 +
+ not clist 03a3 03c2 03c3 ++
Ket
End
------------------------------------------------------------------
@@ -1469,5 +1508,759 @@ No match
/is{2}t/8i
iskt
No match
+
+/-- This property is a PCRE special --/
+
+/^\p{Xuc}/8
+ $abc
+ 0: $
+ @abc
+ 0: @
+ `abc
+ 0: `
+ \x{1234}abc
+ 0: \x{1234}
+ ** Failers
+No match
+ abc
+No match
+
+/^\p{Xuc}+/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}\x{e000}
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\p{Xuc}+?/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\p{Xuc}+?\*/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}\x{e000}*
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\p{Xuc}++/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}\x{e000}
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\p{Xuc}{3,5}/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\p{Xuc}{3,5}?/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^[\p{Xuc}]/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^[\p{Xuc}]+/8
+ $@`\x{a0}\x{1234}\x{e000}**
+ 0: $@`\x{a0}\x{1234}\x{e000}
+ ** Failers
+No match
+ \x{9f}
+No match
+
+/^\P{Xuc}/8
+ abc
+ 0: a
+ ** Failers
+ 0: *
+ $abc
+No match
+ @abc
+No match
+ `abc
+No match
+ \x{1234}abc
+No match
+
+/^[\P{Xuc}]/8
+ abc
+ 0: a
+ ** Failers
+ 0: *
+ $abc
+No match
+ @abc
+No match
+ `abc
+No match
+ \x{1234}abc
+No match
+
+/-- Some auto-possessification tests --/
+
+/\pN+\z/BZ
+------------------------------------------------------------------
+ Bra
+ prop N ++
+ \z
+ Ket
+ End
+------------------------------------------------------------------
+
+/\PN+\z/BZ
+------------------------------------------------------------------
+ Bra
+ notprop N ++
+ \z
+ Ket
+ End
+------------------------------------------------------------------
+
+/\pN+/BZ
+------------------------------------------------------------------
+ Bra
+ prop N ++
+ Ket
+ End
+------------------------------------------------------------------
+
+/\PN+/BZ
+------------------------------------------------------------------
+ Bra
+ notprop N ++
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Any}+\p{Any} \p{Any}+\P{Any} \p{Any}+\p{L&} \p{Any}+\p{L} \p{Any}+\p{Lu} \p{Any}+\p{Han} \p{Any}+\p{Xan} \p{Any}+\p{Xsp} \p{Any}+\p{Xps} \p{Xwd}+\p{Any} \p{Any}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Any +
+ prop Any
+ prop Any +
+ notprop Any
+ prop Any +
+ prop L&
+ prop Any +
+ prop L
+ prop Any +
+ prop Lu
+ prop Any +
+ prop Han
+ prop Any +
+ prop Xan
+ prop Any +
+ prop Xsp
+ prop Any +
+ prop Xps
+ prop Xwd +
+ prop Any
+ prop Any +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{L&}+\p{Any} \p{L&}+\p{L&} \P{L&}+\p{L&} \p{L&}+\p{L} \p{L&}+\p{Lu} \p{L&}+\p{Han} \p{L&}+\p{Xan} \p{L&}+\P{Xan} \p{L&}+\p{Xsp} \p{L&}+\p{Xps} \p{Xwd}+\p{L&} \p{L&}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop L& +
+ prop Any
+ prop L& +
+ prop L&
+ notprop L& ++
+ prop L&
+ prop L& +
+ prop L
+ prop L& +
+ prop Lu
+ prop L& +
+ prop Han
+ prop L& +
+ prop Xan
+ prop L& ++
+ notprop Xan
+ prop L& ++
+ prop Xsp
+ prop L& ++
+ prop Xps
+ prop Xwd +
+ prop L&
+ prop L& +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{N}+\p{Any} \p{N}+\p{L&} \p{N}+\p{L} \p{N}+\P{L} \p{N}+\P{N} \p{N}+\p{Lu} \p{N}+\p{Han} \p{N}+\p{Xan} \p{N}+\p{Xsp} \p{N}+\p{Xps} \p{Xwd}+\p{N} \p{N}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop N +
+ prop Any
+ prop N +
+ prop L&
+ prop N ++
+ prop L
+ prop N +
+ notprop L
+ prop N ++
+ notprop N
+ prop N ++
+ prop Lu
+ prop N +
+ prop Han
+ prop N +
+ prop Xan
+ prop N ++
+ prop Xsp
+ prop N ++
+ prop Xps
+ prop Xwd +
+ prop N
+ prop N +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Lu}+\p{Any} \p{Lu}+\p{L&} \p{Lu}+\p{L} \p{Lu}+\p{Lu} \P{Lu}+\p{Lu} \p{Lu}+\p{Nd} \p{Lu}+\P{Nd} \p{Lu}+\p{Han} \p{Lu}+\p{Xan} \p{Lu}+\p{Xsp} \p{Lu}+\p{Xps} \p{Xwd}+\p{Lu} \p{Lu}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Lu +
+ prop Any
+ prop Lu +
+ prop L&
+ prop Lu +
+ prop L
+ prop Lu +
+ prop Lu
+ notprop Lu ++
+ prop Lu
+ prop Lu ++
+ prop Nd
+ prop Lu +
+ notprop Nd
+ prop Lu +
+ prop Han
+ prop Lu +
+ prop Xan
+ prop Lu ++
+ prop Xsp
+ prop Lu ++
+ prop Xps
+ prop Xwd +
+ prop Lu
+ prop Lu +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Han}+\p{Lu} \p{Han}+\p{L&} \p{Han}+\p{L} \p{Han}+\p{Lu} \p{Han}+\p{Arabic} \p{Arabic}+\p{Arabic} \p{Han}+\p{Xan} \p{Han}+\p{Xsp} \p{Han}+\p{Xps} \p{Xwd}+\p{Han} \p{Han}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Han +
+ prop Lu
+ prop Han +
+ prop L&
+ prop Han +
+ prop L
+ prop Han +
+ prop Lu
+ prop Han ++
+ prop Arabic
+ prop Arabic +
+ prop Arabic
+ prop Han +
+ prop Xan
+ prop Han +
+ prop Xsp
+ prop Han +
+ prop Xps
+ prop Xwd +
+ prop Han
+ prop Han +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xan}+\p{Any} \p{Xan}+\p{L&} \P{Xan}+\p{L&} \p{Xan}+\p{L} \p{Xan}+\p{Lu} \p{Xan}+\p{Han} \p{Xan}+\p{Xan} \p{Xan}+\P{Xan} \p{Xan}+\p{Xsp} \p{Xan}+\p{Xps} \p{Xwd}+\p{Xan} \p{Xan}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xan +
+ prop Any
+ prop Xan +
+ prop L&
+ notprop Xan ++
+ prop L&
+ prop Xan +
+ prop L
+ prop Xan +
+ prop Lu
+ prop Xan +
+ prop Han
+ prop Xan +
+ prop Xan
+ prop Xan ++
+ notprop Xan
+ prop Xan ++
+ prop Xsp
+ prop Xan ++
+ prop Xps
+ prop Xwd +
+ prop Xan
+ prop Xan +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xsp}+\p{Any} \p{Xsp}+\p{L&} \p{Xsp}+\p{L} \p{Xsp}+\p{Lu} \p{Xsp}+\p{Han} \p{Xsp}+\p{Xan} \p{Xsp}+\p{Xsp} \P{Xsp}+\p{Xsp} \p{Xsp}+\p{Xps} \p{Xwd}+\p{Xsp} \p{Xsp}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xsp +
+ prop Any
+ prop Xsp ++
+ prop L&
+ prop Xsp ++
+ prop L
+ prop Xsp ++
+ prop Lu
+ prop Xsp +
+ prop Han
+ prop Xsp ++
+ prop Xan
+ prop Xsp +
+ prop Xsp
+ notprop Xsp ++
+ prop Xsp
+ prop Xsp +
+ prop Xps
+ prop Xwd ++
+ prop Xsp
+ prop Xsp +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xwd}+\p{Any} \p{Xwd}+\p{L&} \p{Xwd}+\p{L} \p{Xwd}+\p{Lu} \p{Xwd}+\p{Han} \p{Xwd}+\p{Xan} \p{Xwd}+\p{Xsp} \p{Xwd}+\p{Xps} \p{Xwd}+\p{Xwd} \p{Xwd}+\P{Xwd} \p{Xwd}+\p{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xwd +
+ prop Any
+ prop Xwd +
+ prop L&
+ prop Xwd +
+ prop L
+ prop Xwd +
+ prop Lu
+ prop Xwd +
+ prop Han
+ prop Xwd +
+ prop Xan
+ prop Xwd ++
+ prop Xsp
+ prop Xwd ++
+ prop Xps
+ prop Xwd +
+ prop Xwd
+ prop Xwd ++
+ notprop Xwd
+ prop Xwd +
+ prop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xuc}+\p{Any} \p{Xuc}+\p{L&} \p{Xuc}+\p{L} \p{Xuc}+\p{Lu} \p{Xuc}+\p{Han} \p{Xuc}+\p{Xan} \p{Xuc}+\p{Xsp} \p{Xuc}+\p{Xps} \p{Xwd}+\p{Xuc} \p{Xuc}+\p{Xuc} \p{Xuc}+\P{Xuc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xuc +
+ prop Any
+ prop Xuc +
+ prop L&
+ prop Xuc +
+ prop L
+ prop Xuc +
+ prop Lu
+ prop Xuc +
+ prop Han
+ prop Xuc +
+ prop Xan
+ prop Xuc +
+ prop Xsp
+ prop Xuc +
+ prop Xps
+ prop Xwd +
+ prop Xuc
+ prop Xuc +
+ prop Xuc
+ prop Xuc ++
+ notprop Xuc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{N}+\p{Ll} \p{N}+\p{Nd} \p{N}+\P{Nd}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop N ++
+ prop Ll
+ prop N +
+ prop Nd
+ prop N +
+ notprop Nd
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xan}+\p{L} \p{Xan}+\p{N} \p{Xan}+\p{C} \p{Xan}+\P{L} \P{Xan}+\p{N} \p{Xan}+\P{C}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xan +
+ prop L
+ prop Xan +
+ prop N
+ prop Xan ++
+ prop C
+ prop Xan +
+ notprop L
+ notprop Xan ++
+ prop N
+ prop Xan +
+ notprop C
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{L}+\p{Xan} \p{N}+\p{Xan} \p{C}+\p{Xan} \P{L}+\p{Xan} \p{N}+\p{Xan} \P{C}+\p{Xan} \p{L}+\P{Xan}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop L +
+ prop Xan
+ prop N +
+ prop Xan
+ prop C ++
+ prop Xan
+ notprop L +
+ prop Xan
+ prop N +
+ prop Xan
+ notprop C +
+ prop Xan
+ prop L ++
+ notprop Xan
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xan}+\p{Lu} \p{Xan}+\p{Nd} \p{Xan}+\p{Cc} \p{Xan}+\P{Ll} \P{Xan}+\p{No} \p{Xan}+\P{Cf}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xan +
+ prop Lu
+ prop Xan +
+ prop Nd
+ prop Xan ++
+ prop Cc
+ prop Xan +
+ notprop Ll
+ notprop Xan ++
+ prop No
+ prop Xan +
+ notprop Cf
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Lu}+\p{Xan} \p{Nd}+\p{Xan} \p{Cs}+\p{Xan} \P{Lt}+\p{Xan} \p{Nl}+\p{Xan} \P{Cc}+\p{Xan} \p{Lt}+\P{Xan}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Lu +
+ prop Xan
+ prop Nd +
+ prop Xan
+ prop Cs ++
+ prop Xan
+ notprop Lt +
+ prop Xan
+ prop Nl +
+ prop Xan
+ notprop Cc +
+ prop Xan
+ prop Lt ++
+ notprop Xan
+ Ket
+ End
+------------------------------------------------------------------
+
+/\w+\p{P} \w+\p{Po} \w+\s \p{Xan}+\s \s+\p{Xan} \s+\w/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xwd +
+ prop P
+ prop Xwd +
+ prop Po
+ prop Xwd ++
+ prop Xsp
+ prop Xan ++
+ prop Xsp
+ prop Xsp ++
+ prop Xan
+ prop Xsp ++
+ prop Xwd
+ Ket
+ End
+------------------------------------------------------------------
+
+/\w+\P{P} \W+\p{Po} \w+\S \P{Xan}+\s \s+\P{Xan} \s+\W/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xwd +
+ notprop P
+ notprop Xwd +
+ prop Po
+ prop Xwd +
+ notprop Xsp
+ notprop Xan +
+ prop Xsp
+ prop Xsp +
+ notprop Xan
+ prop Xsp +
+ notprop Xwd
+ Ket
+ End
+------------------------------------------------------------------
+
+/\w+\p{Po} \w+\p{Pc} \W+\p{Po} \W+\p{Pc} \w+\P{Po} \w+\P{Pc}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xwd +
+ prop Po
+ prop Xwd ++
+ prop Pc
+ notprop Xwd +
+ prop Po
+ notprop Xwd +
+ prop Pc
+ prop Xwd +
+ notprop Po
+ prop Xwd +
+ notprop Pc
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Nl}+\p{Xan} \P{Nl}+\p{Xan} \p{Nl}+\P{Xan} \P{Nl}+\P{Xan}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Nl +
+ prop Xan
+ notprop Nl +
+ prop Xan
+ prop Nl ++
+ notprop Xan
+ notprop Nl +
+ notprop Xan
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xan}+\p{Nl} \P{Xan}+\p{Nl} \p{Xan}+\P{Nl} \P{Xan}+\P{Nl}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xan +
+ prop Nl
+ notprop Xan ++
+ prop Nl
+ prop Xan +
+ notprop Nl
+ notprop Xan +
+ notprop Nl
+ Ket
+ End
+------------------------------------------------------------------
+
+/\p{Xan}+\p{Nd} \P{Xan}+\p{Nd} \p{Xan}+\P{Nd} \P{Xan}+\P{Nd}/BWZx
+------------------------------------------------------------------
+ Bra
+ prop Xan +
+ prop Nd
+ notprop Xan ++
+ prop Nd
+ prop Xan +
+ notprop Nd
+ notprop Xan +
+ notprop Nd
+ Ket
+ End
+------------------------------------------------------------------
+
+/-- End auto-possessification tests --/
+
+/\w+/8CWBZ
+------------------------------------------------------------------
+ Bra
+ Callout 255 0 3
+ prop Xwd ++
+ Callout 255 3 0
+ Ket
+ End
+------------------------------------------------------------------
+ abcd
+--->abcd
+ +0 ^ \w+
+ +3 ^ ^
+ 0: abcd
+
+/[\p{N}]?+/BZO
+------------------------------------------------------------------
+ Bra
+ [\p{N}]?+
+ Ket
+ End
+------------------------------------------------------------------
+
+/[\p{L}ab]{2,3}+/BZO
+------------------------------------------------------------------
+ Bra
+ [ab\p{L}]{2,3}+
+ Ket
+ End
+------------------------------------------------------------------
+
+/\D+\X \d+\X \S+\X \s+\X \W+\X \w+\X \C+\X \R+\X \H+\X \h+\X \V+\X \v+\X a+\X \n+\X .+\X/BZx
+------------------------------------------------------------------
+ Bra
+ \D+
+ extuni
+ \d+
+ extuni
+ \S+
+ extuni
+ \s+
+ extuni
+ \W+
+ extuni
+ \w+
+ extuni
+ AllAny+
+ extuni
+ \R+
+ extuni
+ \H+
+ extuni
+ \h+
+ extuni
+ \V+
+ extuni
+ \v+
+ extuni
+ a+
+ extuni
+ \x0a+
+ extuni
+ Any+
+ extuni
+ Ket
+ End
+------------------------------------------------------------------
+
+/.+\X/BZxs
+------------------------------------------------------------------
+ Bra
+ AllAny+
+ extuni
+ Ket
+ End
+------------------------------------------------------------------
+
+/\X+$/BZxm
+------------------------------------------------------------------
+ Bra
+ extuni+
+ /m $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\X+\D \X+\d \X+\S \X+\s \X+\W \X+\w \X+. \X+\C \X+\R \X+\H \X+\h \X+\V \X+\v \X+\X \X+\Z \X+\z \X+$/BZx
+------------------------------------------------------------------
+ Bra
+ extuni+
+ \D
+ extuni+
+ \d
+ extuni+
+ \S
+ extuni+
+ \s
+ extuni+
+ \W
+ extuni+
+ \w
+ extuni+
+ Any
+ extuni+
+ AllAny
+ extuni+
+ \R
+ extuni+
+ \H
+ extuni+
+ \h
+ extuni+
+ \V
+ extuni+
+ \v
+ extuni+
+ extuni
+ extuni+
+ \Z
+ extuni++
+ \z
+ extuni+
+ $
+ Ket
+ End
+------------------------------------------------------------------
+
+/\d+\s{0,5}=\s*\S?=\w{0,4}\W*/8WBZ
+------------------------------------------------------------------
+ Bra
+ prop Nd ++
+ prop Xsp {0,5}+
+ =
+ prop Xsp *+
+ notprop Xsp ?
+ =
+ prop Xwd {0,4}+
+ notprop Xwd *+
+ Ket
+ End
+------------------------------------------------------------------
/-- End of testinput7 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput8 b/ext/pcre/pcrelib/testdata/testoutput8
index 73e0eae87b..bb68d3e645 100644
--- a/ext/pcre/pcrelib/testdata/testoutput8
+++ b/ext/pcre/pcrelib/testdata/testoutput8
@@ -1,5 +1,8 @@
-/-- This set of tests check the DFA matching functionality of pcre_dfa_exec().
- The -dfa flag must be used with pcretest when running it. --/
+/-- This set of tests check the DFA matching functionality of pcre_dfa_exec(),
+ excluding UTF and Unicode property support. The -dfa flag must be used with
+ pcretest when running it. --/
+
+< forbid 8W
/abc/
abc
@@ -25,7 +28,7 @@ No match
ab
No match
-/a*/
+/a*/O
a
0: a
1:
@@ -49,7 +52,7 @@ No match
16: a
17:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-Matched, but too many subsidiary matches
+Matched, but offsets vector is too small to show all matches
0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
2: aaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -341,7 +344,7 @@ No match
axyzq
No match
-/[^a]+/
+/[^a]+/O
bac
0: b
bcdefax
@@ -359,7 +362,7 @@ No match
aaaaa
No match
-/[^a]*/
+/[^a]*/O
bac
0: b
1:
@@ -380,7 +383,7 @@ No match
aaaaa
0:
-/[^a]{3,5}/
+/[^a]{3,5}/O
xyz
0: xyz
awxyza
@@ -408,29 +411,18 @@ No match
/\d*/
1234b567
0: 1234
- 1: 123
- 2: 12
- 3: 1
- 4:
xyz
0:
/\D*/
a1234b567
0: a
- 1:
xyz
0: xyz
- 1: xy
- 2: x
- 3:
/\d+/
ab1234c56
0: 1234
- 1: 123
- 2: 12
- 3: 1
*** Failers
No match
xyz
@@ -439,19 +431,8 @@ No match
/\D+/
ab123c56
0: ab
- 1: a
*** Failers
0: *** Failers
- 1: *** Failer
- 2: *** Faile
- 3: *** Fail
- 4: *** Fai
- 5: *** Fa
- 6: *** F
- 7: ***
- 8: ***
- 9: **
-10: *
789
No match
@@ -478,9 +459,6 @@ No match
/a+/
aaaa
0: aaaa
- 1: aaa
- 2: aa
- 3: a
/^.*xyz/
xyz
@@ -886,9 +864,6 @@ No match
0:
aaabcd
0: aaa
- 1: aa
- 2: a
- 3:
xyz
0: xyz
1:
@@ -985,7 +960,7 @@ Partial match: abc
xyzfo\P
No match
foob\P\>2
-Partial match: foob
+Partial match at offset 3: foob
foobar...\R\P\>4
0: ar
xyzfo\P
@@ -1577,18 +1552,6 @@ No match
/^[.^$|()*+?{,}]+/
.^\$(*+)|{?,?}
0: .^$(*+)|{?,?}
- 1: .^$(*+)|{?,?
- 2: .^$(*+)|{?,
- 3: .^$(*+)|{?
- 4: .^$(*+)|{
- 5: .^$(*+)|
- 6: .^$(*+)
- 7: .^$(*+
- 8: .^$(*
- 9: .^$(
-10: .^$
-11: .^
-12: .
/^a*\w/
z
@@ -1744,38 +1707,16 @@ No match
/foo(?!bar)(.*)/
foobar is foolish see?
0: foolish see?
- 1: foolish see
- 2: foolish se
- 3: foolish s
- 4: foolish
- 5: foolish
- 6: foolis
- 7: fooli
- 8: fool
- 9: foo
/(?:(?!foo)...|^.{0,2})bar(.*)/
foobar crowbar etc
0: rowbar etc
- 1: rowbar et
- 2: rowbar e
- 3: rowbar
- 4: rowbar
barrel
0: barrel
- 1: barre
- 2: barr
- 3: bar
2barrel
0: 2barrel
- 1: 2barre
- 2: 2barr
- 3: 2bar
A barrel
0: A barrel
- 1: A barre
- 2: A barr
- 3: A bar
/^(\D*)(?=\d)(?!123)/
abc456
@@ -1820,7 +1761,7 @@ No match
the abc
No match
-/^[ab]{1,3}(ab*|b)/
+/^[ab]{1,3}(ab*|b)/O
aabbbbb
0: aabbbbb
1: aabbbb
@@ -1829,7 +1770,7 @@ No match
4: aab
5: aa
-/^[ab]{1,3}?(ab*|b)/
+/^[ab]{1,3}?(ab*|b)/O
aabbbbb
0: aabbbbb
1: aabbbb
@@ -1838,7 +1779,7 @@ No match
4: aab
5: aa
-/^[ab]{1,3}?(ab*?|b)/
+/^[ab]{1,3}?(ab*?|b)/O
aabbbbb
0: aabbbbb
1: aabbbb
@@ -1847,7 +1788,7 @@ No match
4: aab
5: aa
-/^[ab]{1,3}(ab*?|b)/
+/^[ab]{1,3}(ab*?|b)/O
aabbbbb
0: aabbbbb
1: aabbbb
@@ -2705,10 +2646,6 @@ No match
/\0*/
\0\0\0\0
0: \x00\x00\x00\x00
- 1: \x00\x00\x00
- 2: \x00\x00
- 3: \x00
- 4:
/A\x0{2,3}Z/
The A\x0\x0Z
@@ -2760,56 +2697,14 @@ No match
/([^.]*)\.([^:]*):[T ]+(.*)/
track1.title:TBlah blah blah
0: track1.title:TBlah blah blah
- 1: track1.title:TBlah blah bla
- 2: track1.title:TBlah blah bl
- 3: track1.title:TBlah blah b
- 4: track1.title:TBlah blah
- 5: track1.title:TBlah blah
- 6: track1.title:TBlah bla
- 7: track1.title:TBlah bl
- 8: track1.title:TBlah b
- 9: track1.title:TBlah
-10: track1.title:TBlah
-11: track1.title:TBla
-12: track1.title:TBl
-13: track1.title:TB
-14: track1.title:T
/([^.]*)\.([^:]*):[T ]+(.*)/i
track1.title:TBlah blah blah
0: track1.title:TBlah blah blah
- 1: track1.title:TBlah blah bla
- 2: track1.title:TBlah blah bl
- 3: track1.title:TBlah blah b
- 4: track1.title:TBlah blah
- 5: track1.title:TBlah blah
- 6: track1.title:TBlah bla
- 7: track1.title:TBlah bl
- 8: track1.title:TBlah b
- 9: track1.title:TBlah
-10: track1.title:TBlah
-11: track1.title:TBla
-12: track1.title:TBl
-13: track1.title:TB
-14: track1.title:T
/([^.]*)\.([^:]*):[t ]+(.*)/i
track1.title:TBlah blah blah
0: track1.title:TBlah blah blah
- 1: track1.title:TBlah blah bla
- 2: track1.title:TBlah blah bl
- 3: track1.title:TBlah blah b
- 4: track1.title:TBlah blah
- 5: track1.title:TBlah blah
- 6: track1.title:TBlah bla
- 7: track1.title:TBlah bl
- 8: track1.title:TBlah b
- 9: track1.title:TBlah
-10: track1.title:TBlah
-11: track1.title:TBla
-12: track1.title:TBl
-13: track1.title:TB
-14: track1.title:T
/^[W-c]+$/
WXY_^abc
@@ -2882,13 +2777,10 @@ No match
0: b
c::b
0: ::
- 1: :
/[-az]+/
az-
0: az-
- 1: az
- 2: a
*** Failers
0: a
b
@@ -2897,8 +2789,6 @@ No match
/[az-]+/
za-
0: za-
- 1: za
- 2: z
*** Failers
0: a
b
@@ -2907,8 +2797,6 @@ No match
/[a\-z]+/
a-z
0: a-z
- 1: a-
- 2: a
*** Failers
0: a
b
@@ -2917,20 +2805,10 @@ No match
/[a-z]+/
abcdxyz
0: abcdxyz
- 1: abcdxy
- 2: abcdx
- 3: abcd
- 4: abc
- 5: ab
- 6: a
/[\d-]+/
12-34
0: 12-34
- 1: 12-3
- 2: 12-
- 3: 12
- 4: 1
*** Failers
No match
aaa
@@ -2939,11 +2817,6 @@ No match
/[\d-z]+/
12-34z
0: 12-34z
- 1: 12-34
- 2: 12-3
- 3: 12-
- 4: 12
- 5: 1
*** Failers
No match
aaa
@@ -3027,18 +2900,22 @@ No match
abc\100\60
0: abc@0
-/abc\81/
- abc\081
- 0: abc\x0081
- abc\0\x38\x31
- 0: abc\x0081
-
-/abc\91/
- abc\091
- 0: abc\x0091
- abc\0\x39\x31
- 0: abc\x0091
-
+/^A\8B\9C$/
+ A8B9C
+ 0: A8B9C
+ *** Failers
+No match
+ A\08B\09C
+No match
+
+/^[A\8B\9C]+$/
+ A8B9C
+ 0: A8B9C
+ *** Failers
+No match
+ A8B9C\x00
+No match
+
/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/
abcdefghijk\12S
0: abcdefghijk\x0aS
@@ -3077,16 +2954,13 @@ No match
1: baNOTccc
2: baNOTcc
3: baNOTc
- 4: baNOT
baNOTcccd
0: baNOTccc
1: baNOTcc
2: baNOTc
- 3: baNOT
baNOTccd
0: baNOTcc
1: baNOTc
- 2: baNOT
bacccd
0: baccc
*** Failers
@@ -3096,7 +2970,6 @@ No match
3: *** Fail
4: *** Fai
5: *** Fa
- 6: *** F
anything
No match
b\bc
@@ -3115,23 +2988,14 @@ No match
/[^a]+/
AAAaAbc
0: AAA
- 1: AA
- 2: A
/[^a]+/i
AAAaAbc
0: bc
- 1: b
/[^a]+/
bbb\nccc
0: bbb\x0accc
- 1: bbb\x0acc
- 2: bbb\x0ac
- 3: bbb\x0a
- 4: bbb
- 5: bb
- 6: b
/[^k]$/
abc
@@ -3208,20 +3072,8 @@ No match
/(\.\d\d[1-9]?)\d+/
1.230003938
0: .230003938
- 1: .23000393
- 2: .2300039
- 3: .230003
- 4: .23000
- 5: .2300
- 6: .230
1.875000282
0: .875000282
- 1: .87500028
- 2: .8750002
- 3: .875000
- 4: .87500
- 5: .8750
- 6: .875
1.235
0: .235
@@ -3243,10 +3095,6 @@ No match
/\b(foo)\s+(\w+)/i
Food is on the foo table
0: foo table
- 1: foo tabl
- 2: foo tab
- 3: foo ta
- 4: foo t
/foo(.*)bar/
The food is under the bar in the barn.
@@ -3258,9 +3106,9 @@ No match
0: food is under the bar in the bar
1: food is under the bar
-/(.*)(\d*)/
+/(.*)(\d*)/O
I have 2 numbers: 53147
-Matched, but too many subsidiary matches
+Matched, but offsets vector is too small to show all matches
0: I have 2 numbers: 53147
1: I have 2 numbers: 5314
2: I have 2 numbers: 531
@@ -3287,15 +3135,11 @@ Matched, but too many subsidiary matches
/(.*)(\d+)/
I have 2 numbers: 53147
0: I have 2 numbers: 53147
- 1: I have 2 numbers: 5314
- 2: I have 2 numbers: 531
- 3: I have 2 numbers: 53
- 4: I have 2 numbers: 5
- 5: I have 2
+ 1: I have 2
-/(.*?)(\d*)/
+/(.*?)(\d*)/O
I have 2 numbers: 53147
-Matched, but too many subsidiary matches
+Matched, but offsets vector is too small to show all matches
0: I have 2 numbers: 53147
1: I have 2 numbers: 5314
2: I have 2 numbers: 531
@@ -3322,11 +3166,7 @@ Matched, but too many subsidiary matches
/(.*?)(\d+)/
I have 2 numbers: 53147
0: I have 2 numbers: 53147
- 1: I have 2 numbers: 5314
- 2: I have 2 numbers: 531
- 3: I have 2 numbers: 53
- 4: I have 2 numbers: 5
- 5: I have 2
+ 1: I have 2
/(.*)(\d+)$/
I have 2 numbers: 53147
@@ -3738,13 +3578,8 @@ No match
0: a
ab
0: ab
- 1: a
abbbb
0: abbbb
- 1: abbb
- 2: abb
- 3: ab
- 4: a
*** Failers
0: a
bbbbb
@@ -3930,19 +3765,8 @@ No match
/(?>(\.\d\d[1-9]?))\d+/
1.230003938
0: .230003938
- 1: .23000393
- 2: .2300039
- 3: .230003
- 4: .23000
- 5: .2300
- 6: .230
1.875000282
0: .875000282
- 1: .87500028
- 2: .8750002
- 3: .875000
- 4: .87500
- 5: .8750
*** Failers
No match
1.235
@@ -4561,7 +4385,6 @@ No match
/.{3,4}/
abbbbc
0: abbb
- 1: abb
/ab{0,}bc/
abbbbc
@@ -4929,9 +4752,6 @@ No match
/[^ab]*/
cde
0: cde
- 1: cd
- 2: c
- 3:
/abc/
*** Failers
@@ -4966,7 +4786,6 @@ No match
/ab*/
xabyabbbz
0: ab
- 1: a
xayabbbz
0: a
@@ -4995,8 +4814,7 @@ No match
/a([bc]*)c*/
abc
0: abc
- 1: ab
- 2: a
+ 1: a
/a([bc]*)(c*d)/
abcd
@@ -5033,10 +4851,6 @@ No match
/[a-zA-Z_][a-zA-Z0-9_]*/
alpha
0: alpha
- 1: alph
- 2: alp
- 3: al
- 4: a
/^a(bc+|b[eh])g|.h$/
abh
@@ -5079,8 +4893,6 @@ No match
/(.*)c(.*)/
abcde
0: abcde
- 1: abcd
- 2: abc
/\((.*), (.*)\)/
(a, b)
@@ -5395,9 +5207,6 @@ No match
/[^ab]*/i
CDE
0: CDE
- 1: CD
- 2: C
- 3:
/abc/i
@@ -5427,7 +5236,6 @@ No match
/ab*/i
XABYABBBZ
0: AB
- 1: A
XAYABBBZ
0: A
@@ -5458,8 +5266,7 @@ No match
/a([bc]*)c*/i
ABC
0: ABC
- 1: AB
- 2: A
+ 1: A
/a([bc]*)(c*d)/i
ABCD
@@ -5490,10 +5297,6 @@ No match
/[a-zA-Z_][a-zA-Z0-9_]*/i
ALPHA
0: ALPHA
- 1: ALPH
- 2: ALP
- 3: AL
- 4: A
/^a(bc+|b[eh])g|.h$/i
ABH
@@ -5546,8 +5349,6 @@ No match
/(.*)c(.*)/i
ABCDE
0: ABCDE
- 1: ABCD
- 2: ABC
/\((.*), (.*)\)/i
(A, B)
@@ -6052,17 +5853,14 @@ No match
/([[:]+)/
a:[b]:
0: :[
- 1: :
/([[=]+)/
a=[b]=
0: =[
- 1: =
/([[.]+)/
a.[b].
0: .[
- 1: .
/((?>a+)b)/
aaab
@@ -6196,26 +5994,12 @@ No match
/a*/g
abbab
0: a
- 1:
0:
0:
0: a
- 1:
0:
0:
-/^[a-\d]/
- abcde
- 0: a
- -things
- 0: -
- 0digit
- 0: 0
- *** Failers
-No match
- bcdef
-No match
-
/^[\d-a]/
abcde
0: a
@@ -6231,36 +6015,22 @@ No match
/[[:space:]]+/
> \x09\x0a\x0c\x0d\x0b<
0: \x09\x0a\x0c\x0d\x0b
- 1: \x09\x0a\x0c\x0d
- 2: \x09\x0a\x0c
- 3: \x09\x0a
- 4: \x09
- 5:
/[[:blank:]]+/
> \x09\x0a\x0c\x0d\x0b<
0: \x09
- 1:
/[\s]+/
> \x09\x0a\x0c\x0d\x0b<
- 0: \x09\x0a\x0c\x0d
- 1: \x09\x0a\x0c
- 2: \x09\x0a
- 3: \x09
- 4:
+ 0: \x09\x0a\x0c\x0d\x0b
/\s+/
> \x09\x0a\x0c\x0d\x0b<
- 0: \x09\x0a\x0c\x0d
- 1: \x09\x0a\x0c
- 2: \x09\x0a
- 3: \x09
- 4:
+ 0: \x09\x0a\x0c\x0d\x0b
/a b/x
ab
-No match
+ 0: ab
/(?!\A)x/m
a\nxb\n
@@ -6563,8 +6333,6 @@ Partial match: 123
/Content-Type\x3A[^\r\n]{6,}/
Content-Type:xxxxxyyy
0: Content-Type:xxxxxyyy
- 1: Content-Type:xxxxxyy
- 2: Content-Type:xxxxxy
/Content-Type\x3A[^\r\n]{6,}z/
Content-Type:xxxxxyyyz
@@ -6661,66 +6429,22 @@ No match
/.*/<lf>
abc\ndef
0: abc
- 1: ab
- 2: a
- 3:
abc\rdef
0: abc\x0ddef
- 1: abc\x0dde
- 2: abc\x0dd
- 3: abc\x0d
- 4: abc
- 5: ab
- 6: a
- 7:
abc\r\ndef
0: abc\x0d
- 1: abc
- 2: ab
- 3: a
- 4:
\<cr>abc\ndef
0: abc\x0adef
- 1: abc\x0ade
- 2: abc\x0ad
- 3: abc\x0a
- 4: abc
- 5: ab
- 6: a
- 7:
\<cr>abc\rdef
0: abc
- 1: ab
- 2: a
- 3:
\<cr>abc\r\ndef
0: abc
- 1: ab
- 2: a
- 3:
\<crlf>abc\ndef
0: abc\x0adef
- 1: abc\x0ade
- 2: abc\x0ad
- 3: abc\x0a
- 4: abc
- 5: ab
- 6: a
- 7:
\<crlf>abc\rdef
0: abc\x0ddef
- 1: abc\x0dde
- 2: abc\x0dd
- 3: abc\x0d
- 4: abc
- 5: ab
- 6: a
- 7:
\<crlf>abc\r\ndef
0: abc
- 1: ab
- 2: a
- 3:
/\w+(.)(.)?def/s
abc\ndef
@@ -7033,10 +6757,8 @@ No match
/\H*\h+\V?\v{3,4}/
\x09\x20\xa0X\x0a\x0b\x0c\x0d\x0a
0: \x09 \xa0X\x0a\x0b\x0c\x0d
- 1: \x09 \xa0X\x0a\x0b\x0c
\x09\x20\xa0\x0a\x0b\x0c\x0d\x0a
0: \x09 \xa0\x0a\x0b\x0c\x0d
- 1: \x09 \xa0\x0a\x0b\x0c
\x09\x20\xa0\x0a\x0b\x0c
0: \x09 \xa0\x0a\x0b\x0c
** Failers
@@ -7047,7 +6769,6 @@ No match
/\H{3,4}/
XY ABCDE
0: ABCD
- 1: ABC
XY PQR ST
0: PQR
@@ -7466,17 +7187,17 @@ Error -16 (item unsupported for DFA matching)
xyzabc123pqr
0: 123
xyzabc12\P
-Partial match: abc12
+Partial match at offset 6: abc12
xyzabc12\P\P
-Partial match: abc12
+Partial match at offset 6: abc12
/\babc\b/
+++abc+++
0: abc
+++ab\P
-Partial match: +ab
+Partial match at offset 3: +ab
+++ab\P\P
-Partial match: +ab
+Partial match at offset 3: +ab
/(?=C)/g+
ABCDECBA
@@ -7531,15 +7252,11 @@ No match
xxxxabcd\P
0: abcd
0+
- 1: abc
xxxxabcd\P\P
Partial match: abcd
dddxxx\R
0: ddd
0+ xxx
- 1: dd
- 2: d
- 3:
xxxxabcd\P\P
Partial match: abcd
xxx\R
@@ -7549,27 +7266,22 @@ Partial match: abcd
/abcd*/i
xxxxabcd\P
0: abcd
- 1: abc
xxxxabcd\P\P
Partial match: abcd
XXXXABCD\P
0: ABCD
- 1: ABC
XXXXABCD\P\P
Partial match: ABCD
/abc\d*/
xxxxabc1\P
0: abc1
- 1: abc
xxxxabc1\P\P
Partial match: abc1
/abc[de]*/
xxxxabcde\P
0: abcde
- 1: abcd
- 2: abc
xxxxabcde\P\P
Partial match: abcde
@@ -7625,7 +7337,7 @@ Error -16 (item unsupported for DFA matching)
/(?<=abc)def/
abc\P\P
-Partial match: abc
+Partial match at offset 3: abc
/abc$/
abc
@@ -7684,11 +7396,8 @@ Partial match: abc
/.+/
abc\>0
0: abc
- 1: ab
- 2: a
abc\>1
0: bc
- 1: b
abc\>2
0: c
abc\>3
@@ -7811,10 +7520,6 @@ No match
/^(?!a){0}\w+/
aaaaa
0: aaaaa
- 1: aaaa
- 2: aaa
- 3: aa
- 4: a
/(?<=(abc))?xyz/
abcxyz
@@ -7846,9 +7551,9 @@ Error -17 (backreference condition or recursion test not supported for DFA match
aaaabcde
Error -26 (nested recursion at the same subject position)
-/(a+)/
+/(a+)/O
\O6aaaa
-Matched, but too many subsidiary matches
+Matched, but offsets vector is too small to show all matches
0: aaaa
1: aaa
2: aa
@@ -7971,7 +7676,6 @@ Partial match: \x0d
Partial match: \x0d\x0d
\r\r\r\P
0: \x0d\x0d\x0d
- 1: \x0d\x0d
\r\r\r\P\P
Partial match: \x0d\x0d\x0d
@@ -8016,4 +7720,61 @@ Error -30 (invalid data in workspace for DFA restart)
0: xx\xa0xxxxxabcd
1: xx\xa0xxxxxabc
+/abcd/
+ abcd\O0
+Matched, but offsets vector is too small to show all matches
+
+/-- These tests show up auto-possessification --/
+
+/[ab]*/
+ aaaa
+ 0: aaaa
+
+/[ab]*?/
+ aaaa
+ 0: aaaa
+ 1: aaa
+ 2: aa
+ 3: a
+ 4:
+
+/[ab]?/
+ aaaa
+ 0: a
+
+/[ab]??/
+ aaaa
+ 0: a
+ 1:
+
+/[ab]+/
+ aaaa
+ 0: aaaa
+
+/[ab]+?/
+ aaaa
+ 0: aaaa
+ 1: aaa
+ 2: aa
+ 3: a
+
+/[ab]{2,3}/
+ aaaa
+ 0: aaa
+
+/[ab]{2,3}?/
+ aaaa
+ 0: aaa
+ 1: aa
+
+/[ab]{2,}/
+ aaaa
+ 0: aaaa
+
+/[ab]{2,}?/
+ aaaa
+ 0: aaaa
+ 1: aaa
+ 2: aa
+
/-- End of testinput8 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutput9 b/ext/pcre/pcrelib/testdata/testoutput9
index 95cd618dc2..efbbf18010 100644
--- a/ext/pcre/pcrelib/testdata/testoutput9
+++ b/ext/pcre/pcrelib/testdata/testoutput9
@@ -1,6 +1,8 @@
/-- This set of tests checks UTF-8 support with the DFA matching functionality
- of pcre_dfa_exec(). The -dfa flag must be used with pcretest when running
- it. --/
+ of pcre_dfa_exec(), excluding Unicode property support. The -dfa flag must
+ be used with pcretest when running it. --/
+
+< forbid W
/\x{100}ab/8
\x{100}ab
@@ -313,13 +315,9 @@ No match
/[^a]+/8g
bcd
0: bcd
- 1: bc
- 2: b
\x{100}aY\x{256}Z
0: \x{100}
0: Y\x{256}Z
- 1: Y\x{256}
- 2: Y
/^[^a]{2}/8
\x{100}bc
@@ -328,8 +326,6 @@ No match
/^[^a]{2,}/8
\x{100}bcAa
0: \x{100}bcA
- 1: \x{100}bc
- 2: \x{100}b
/^[^a]{2,}?/8
\x{100}bca
@@ -339,13 +335,9 @@ No match
/[^a]+/8ig
bcd
0: bcd
- 1: bc
- 2: b
\x{100}aY\x{256}Z
0: \x{100}
0: Y\x{256}Z
- 1: Y\x{256}
- 2: Y
/^[^a]{2}/8i
\x{100}bc
@@ -354,7 +346,6 @@ No match
/^[^a]{2,}/8i
\x{100}bcAa
0: \x{100}bc
- 1: \x{100}b
/^[^a]{2,}?/8i
\x{100}bca
@@ -370,28 +361,18 @@ No match
0:
\x{100}\x{100}
0: \x{100}
- 1:
/\x{100}{0,3}/8
\x{100}\x{100}
0: \x{100}\x{100}
- 1: \x{100}
- 2:
\x{100}\x{100}\x{100}\x{100}
0: \x{100}\x{100}\x{100}
- 1: \x{100}\x{100}
- 2: \x{100}
- 3:
/\x{100}*/8
abce
0:
\x{100}\x{100}\x{100}\x{100}
0: \x{100}\x{100}\x{100}\x{100}
- 1: \x{100}\x{100}\x{100}
- 2: \x{100}\x{100}
- 3: \x{100}
- 4:
/\x{100}{1,1}/8
abcd\x{100}\x{100}\x{100}\x{100}
@@ -400,15 +381,10 @@ No match
/\x{100}{1,3}/8
abcd\x{100}\x{100}\x{100}\x{100}
0: \x{100}\x{100}\x{100}
- 1: \x{100}\x{100}
- 2: \x{100}
/\x{100}+/8
abcd\x{100}\x{100}\x{100}\x{100}
0: \x{100}\x{100}\x{100}\x{100}
- 1: \x{100}\x{100}\x{100}
- 2: \x{100}\x{100}
- 3: \x{100}
/\x{100}{3}/8
abcd\x{100}\x{100}\x{100}XX
@@ -417,10 +393,8 @@ No match
/\x{100}{3,5}/8
abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX
0: \x{100}\x{100}\x{100}\x{100}\x{100}
- 1: \x{100}\x{100}\x{100}\x{100}
- 2: \x{100}\x{100}\x{100}
-/\x{100}{3,}/8
+/\x{100}{3,}/8O
abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX
0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
1: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
@@ -432,9 +406,9 @@ No match
Xyyya\x{100}\x{100}bXzzz
0: X
-/\D*/8
+/\D*/8O
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-Matched, but too many subsidiary matches
+Matched, but offsets vector is too small to show all matches
0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -458,9 +432,9 @@ Matched, but too many subsidiary matches
20: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
21: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-/\D*/8
+/\D*/8O
\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
-Matched, but too many subsidiary matches
+Matched, but offsets vector is too small to show all matches
0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
1: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
2: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}
@@ -507,33 +481,18 @@ Matched, but too many subsidiary matches
/\D+/8
12abcd34
0: abcd
- 1: abc
- 2: ab
- 3: a
*** Failers
0: *** Failers
- 1: *** Failer
- 2: *** Faile
- 3: *** Fail
- 4: *** Fai
- 5: *** Fa
- 6: *** F
- 7: ***
- 8: ***
- 9: **
-10: *
1234
No match
/\D{2,3}/8
12abcd34
0: abc
- 1: ab
12ab34
0: ab
*** Failers
0: ***
- 1: **
1234
No match
12a34
@@ -556,7 +515,6 @@ No match
/\d+/8
12abcd34
0: 12
- 1: 1
*** Failers
No match
@@ -565,7 +523,6 @@ No match
0: 12
1234abcd
0: 123
- 1: 12
*** Failers
No match
1.4
@@ -585,30 +542,18 @@ No match
/\S+/8
12abcd34
0: 12abcd34
- 1: 12abcd3
- 2: 12abcd
- 3: 12abc
- 4: 12ab
- 5: 12a
- 6: 12
- 7: 1
*** Failers
0: ***
- 1: **
- 2: *
\ \
No match
/\S{2,3}/8
12abcd34
0: 12a
- 1: 12
1234abcd
0: 123
- 1: 12
*** Failers
0: ***
- 1: **
\ \
No match
@@ -654,15 +599,8 @@ No match
/\w+/8
12 34
0: 12
- 1: 1
*** Failers
0: Failers
- 1: Failer
- 2: Faile
- 3: Fail
- 4: Fai
- 5: Fa
- 6: F
+++=*!
No match
@@ -671,10 +609,8 @@ No match
0: ab
abcd ce
0: abc
- 1: ab
*** Failers
0: Fai
- 1: Fa
a.b.c
No match
@@ -693,26 +629,18 @@ No match
/\W+/8
12====34
0: ====
- 1: ===
- 2: ==
- 3: =
*** Failers
0: ***
- 1: ***
- 2: **
- 3: *
abcd
No match
/\W{2,3}/8
ab====cd
0: ===
- 1: ==
ab==cd
0: ==
*** Failers
0: ***
- 1: **
a.b.c
No match
@@ -825,8 +753,6 @@ No match
0: \x{200}
ab\x{200}\x{100}\x{200}\x{100}cd
0: \x{200}\x{100}\x{200}
- 1: \x{200}\x{100}
- 2: \x{200}
*** Failers
No match
@@ -849,8 +775,6 @@ No match
0: \x{200}
ab\x{200}\x{100}\x{200}\x{100}cd
0: \x{200}\x{100}\x{200}
- 1: \x{200}\x{100}
- 2: \x{200}
*** Failers
No match
@@ -1126,21 +1050,21 @@ No match
a\r
No match
-/\h+\V?\v{3,4}/8
+/\h+\V?\v{3,4}/8O
\x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d}
1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}
-/\V?\v{3,4}/8
+/\V?\v{3,4}/8O
\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
0: X\x{0a}\x{0b}\x{0c}\x{0d}
1: X\x{0a}\x{0b}\x{0c}
-/\h+\V?\v{3,4}/8
+/\h+\V?\v{3,4}/8O
>\x09\x20\x{a0}X\x0a\x0a\x0a<
0: \x{09} \x{a0}X\x{0a}\x{0a}\x{0a}
-/\V?\v{3,4}/8
+/\V?\v{3,4}/8O
>\x09\x20\x{a0}X\x0a\x0a\x0a<
0: X\x{0a}\x{0a}\x{0a}
@@ -1154,7 +1078,7 @@ No match
\x{a0} X\x0a
No match
-/\H*\h+\V?\v{3,4}/8
+/\H*\h+\V?\v{3,4}/8O
\x09\x20\x{a0}X\x0a\x0b\x0c\x0d\x0a
0: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}\x{0d}
1: \x{09} \x{a0}X\x{0a}\x{0b}\x{0c}
@@ -1178,7 +1102,7 @@ No match
\x{2009} X\x0a
No match
-/\H*\h+\V?\v{3,4}/8
+/\H*\h+\V?\v{3,4}/8O
\x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x0c\x0d\x0a
0: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}\x{0d}
1: \x{1680}\x{180e}\x{2007}X\x{2028}\x{2029}\x{0c}
@@ -1279,34 +1203,28 @@ No match
/abcd*/8
xxxxabcd\P
0: abcd
- 1: abc
xxxxabcd\P\P
Partial match: abcd
/abcd*/i8
xxxxabcd\P
0: abcd
- 1: abc
xxxxabcd\P\P
Partial match: abcd
XXXXABCD\P
0: ABCD
- 1: ABC
XXXXABCD\P\P
Partial match: ABCD
/abc\d*/8
xxxxabc1\P
0: abc1
- 1: abc
xxxxabc1\P\P
Partial match: abc1
/abc[de]*/8
xxxxabcde\P
0: abcde
- 1: abcd
- 2: abc
xxxxabcde\P\P
Partial match: abcde
@@ -1340,7 +1258,6 @@ Partial match: \x{0d}
Partial match: \x{0d}\x{0d}
\r\r\r\P
0: \x{0d}\x{0d}\x{0d}
- 1: \x{0d}\x{0d}
\r\r\r\P\P
Partial match: \x{0d}\x{0d}\x{0d}
@@ -1366,6 +1283,5 @@ Partial match: \x{0d}\x{0d}\x{0d}
/[^\x{100}]+/8
\x{100}\x{101}X
0: \x{101}X
- 1: \x{101}
/-- End of testinput9 --/
diff --git a/ext/pcre/pcrelib/testdata/testoutputEBC b/ext/pcre/pcrelib/testdata/testoutputEBC
new file mode 100644
index 0000000000..abbfdc43fc
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/testoutputEBC
@@ -0,0 +1,182 @@
+/-- This is a specialized test for checking, when PCRE is compiled with the
+EBCDIC option but in an ASCII environment, that newline and white space
+functionality is working. It catches cases where explicit values such as 0x0a
+have been used instead of names like CHAR_LF. Needless to say, it is not a
+genuine EBCDIC test! In patterns, alphabetic characters that follow a backslash
+must be in EBCDIC code. In data, newlines and other spacing characters must be
+in EBCDIC, but can be specified as escapes. --/
+
+/-- Test default newline and variations --/
+
+/^A/m
+ ABC
+ 0: A
+ 12\x15ABC
+ 0: A
+
+/^A/m<any>
+ 12\x15ABC
+ 0: A
+ 12\x0dABC
+ 0: A
+ 12\x0d\x15ABC
+ 0: A
+ 12\x25ABC
+ 0: A
+
+/^A/m<anycrlf>
+ 12\x15ABC
+ 0: A
+ 12\x0dABC
+ 0: A
+ 12\x0d\x15ABC
+ 0: A
+ ** Fail
+No match
+ 12\x25ABC
+No match
+
+/-- Test \h --/
+
+/^A\/
+ A B
+ 0: A\x20
+
+/-- Test \H --/
+
+/^A\/
+ AB
+ 0: AB
+ ** Fail
+No match
+ A B
+No match
+
+/-- Test \R --/
+
+/^A\/
+ A\x15B
+ 0: A\x15
+ A\x0dB
+ 0: A\x0d
+ A\x25B
+ 0: A\x25
+ A\x0bB
+ 0: A\x0b
+ A\x0cB
+ 0: A\x0c
+ ** Fail
+No match
+ A B
+No match
+
+/-- Test \v --/
+
+/^A\/
+ A\x15B
+ 0: A\x15
+ A\x0dB
+ 0: A\x0d
+ A\x25B
+ 0: A\x25
+ A\x0bB
+ 0: A\x0b
+ A\x0cB
+ 0: A\x0c
+ ** Fail
+No match
+ A B
+No match
+
+/-- Test \V --/
+
+/^A\/
+ A B
+ 0: A\x20
+ ** Fail
+No match
+ A\x15B
+No match
+ A\x0dB
+No match
+ A\x25B
+No match
+ A\x0bB
+No match
+ A\x0cB
+No match
+
+/-- For repeated items, use an atomic group so that the output is the same
+for DFA matching (otherwise it may show multiple matches). --/
+
+/-- Test \h+ --/
+
+/^A(?>\+)/
+ A B
+ 0: A\x20
+
+/-- Test \H+ --/
+
+/^A(?>\+)/
+ AB
+ 0: AB
+ ** Fail
+No match
+ A B
+No match
+
+/-- Test \R+ --/
+
+/^A(?>\+)/
+ A\x15B
+ 0: A\x15
+ A\x0dB
+ 0: A\x0d
+ A\x25B
+ 0: A\x25
+ A\x0bB
+ 0: A\x0b
+ A\x0cB
+ 0: A\x0c
+ ** Fail
+No match
+ A B
+No match
+
+/-- Test \v+ --/
+
+/^A(?>\+)/
+ A\x15B
+ 0: A\x15
+ A\x0dB
+ 0: A\x0d
+ A\x25B
+ 0: A\x25
+ A\x0bB
+ 0: A\x0b
+ A\x0cB
+ 0: A\x0c
+ ** Fail
+No match
+ A B
+No match
+
+/-- Test \V+ --/
+
+/^A(?>\+)/
+ A B
+ 0: A\x20B
+ ** Fail
+No match
+ A\x15B
+No match
+ A\x0dB
+No match
+ A\x25B
+No match
+ A\x0bB
+No match
+ A\x0cB
+No match
+
+/-- End --/
diff --git a/ext/pcre/pcrelib/testdata/wintestinput3 b/ext/pcre/pcrelib/testdata/wintestinput3
new file mode 100644
index 0000000000..04e76a6dc8
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/wintestinput3
@@ -0,0 +1,91 @@
+/^[\w]+/
+ *** Failers
+ cole
+
+/^[\w]+/Lfrench
+ cole
+
+/^[\w]+/
+ *** Failers
+ cole
+
+/^[\W]+/
+ cole
+
+/^[\W]+/Lfrench
+ *** Failers
+ cole
+
+/[\b]/
+ \b
+ *** Failers
+ a
+
+/[\b]/Lfrench
+ \b
+ *** Failers
+ a
+
+/^\w+/
+ *** Failers
+ cole
+
+/^\w+/Lfrench
+ cole
+
+/(.+)\b(.+)/
+ cole
+
+/(.+)\b(.+)/Lfrench
+ *** Failers
+ cole
+
+/cole/i
+ cole
+ *** Failers
+ cole
+
+/cole/iLfrench
+ cole
+ cole
+
+/\w/IS
+
+/\w/ISLfrench
+
+/^[\xc8-\xc9]/iLfrench
+ cole
+ cole
+
+/^[\xc8-\xc9]/Lfrench
+ cole
+ *** Failers
+ cole
+
+/\W+/Lfrench
+ >>>\xaa<<<
+ >>>\xba<<<
+
+/[\W]+/Lfrench
+ >>>\xaa<<<
+ >>>\xba<<<
+
+/[^[:alpha:]]+/Lfrench
+ >>>\xaa<<<
+ >>>\xba<<<
+
+/\w+/Lfrench
+ >>>\xaa<<<
+ >>>\xba<<<
+
+/[\w]+/Lfrench
+ >>>\xaa<<<
+ >>>\xba<<<
+
+/[[:alpha:]]+/Lfrench
+ >>>\xaa<<<
+ >>>\xba<<<
+
+/[[:alpha:]][[:lower:]][[:upper:]]/DZLfrench
+
+/ End of testinput3 /
diff --git a/ext/pcre/pcrelib/testdata/wintestoutput3 b/ext/pcre/pcrelib/testdata/wintestoutput3
new file mode 100644
index 0000000000..0088007067
--- /dev/null
+++ b/ext/pcre/pcrelib/testdata/wintestoutput3
@@ -0,0 +1,166 @@
+/^[\w]+/
+ *** Failers
+No match
+ cole
+No match
+
+/^[\w]+/Lfrench
+ cole
+ 0: cole
+
+/^[\w]+/
+ *** Failers
+No match
+ cole
+No match
+
+/^[\W]+/
+ cole
+ 0: \xc9
+
+/^[\W]+/Lfrench
+ *** Failers
+ 0: ***
+ cole
+No match
+
+/[\b]/
+ \b
+ 0: \x08
+ *** Failers
+No match
+ a
+No match
+
+/[\b]/Lfrench
+ \b
+ 0: \x08
+ *** Failers
+No match
+ a
+No match
+
+/^\w+/
+ *** Failers
+No match
+ cole
+No match
+
+/^\w+/Lfrench
+ cole
+ 0: cole
+
+/(.+)\b(.+)/
+ cole
+ 0: \xc9cole
+ 1: \xc9
+ 2: cole
+
+/(.+)\b(.+)/Lfrench
+ *** Failers
+ 0: *** Failers
+ 1: ***
+ 2: Failers
+ cole
+No match
+
+/cole/i
+ cole
+ 0: \xc9cole
+ *** Failers
+No match
+ cole
+No match
+
+/cole/iLfrench
+ cole
+ 0: cole
+ cole
+ 0: cole
+
+/\w/IS
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+ Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z
+
+/\w/ISLfrench
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Subject length lower bound = 1
+Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P
+ Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z
+
+
+
+
+/^[\xc8-\xc9]/iLfrench
+ cole
+ 0:
+ cole
+ 0:
+
+/^[\xc8-\xc9]/Lfrench
+ cole
+ 0:
+ *** Failers
+No match
+ cole
+No match
+
+/\W+/Lfrench
+ >>>\xaa<<<
+ 0: >>>
+ >>>\xba<<<
+ 0: >>>
+
+/[\W]+/Lfrench
+ >>>\xaa<<<
+ 0: >>>
+ >>>\xba<<<
+ 0: >>>
+
+/[^[:alpha:]]+/Lfrench
+ >>>\xaa<<<
+ 0: >>>
+ >>>\xba<<<
+ 0: >>>
+
+/\w+/Lfrench
+ >>>\xaa<<<
+ 0:
+ >>>\xba<<<
+ 0:
+
+/[\w]+/Lfrench
+ >>>\xaa<<<
+ 0:
+ >>>\xba<<<
+ 0:
+
+/[[:alpha:]]+/Lfrench
+ >>>\xaa<<<
+ 0:
+ >>>\xba<<<
+ 0:
+
+/[[:alpha:]][[:lower:]][[:upper:]]/DZLfrench
+------------------------------------------------------------------
+ Bra
+ [A-Za-z\x83\x8a\x8c\x8e\x9a\x9c\x9e\x9f\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\xff]
+ [a-z\x83\x9a\x9c\x9e\xaa\xb5\xba\xdf-\xf6\xf8-\xff]
+ [A-Z\x8a\x8c\x8e\x9f\xc0-\xd6\xd8-\xde]
+ Ket
+ End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/ End of testinput3 /
diff --git a/ext/pcre/pcrelib/ucp.h b/ext/pcre/pcrelib/ucp.h
index 21039106e5..d8b34bfcc5 100644
--- a/ext/pcre/pcrelib/ucp.h
+++ b/ext/pcre/pcrelib/ucp.h
@@ -11,7 +11,10 @@ should always be at the end of each enum, for backwards compatibility.
IMPORTANT: Note also that the specific numeric values of the enums have to be
the same as the values that are generated by the maint/MultiStage2.py script,
-where the equivalent property descriptive names are listed in vectors. */
+where the equivalent property descriptive names are listed in vectors.
+
+ALSO: The specific values of the first two enums are assumed for the table
+called catposstab in pcre_compile.c. */
/* These are the general character categories. */